0

MVC4 で json をオブジェクトにデシリアライズしようとすると問題が発生します。

ビューモデルがあります:

 public class TestViewModel
{
    public string Code { get; set; }

}

ビューでモデルを取得し、Json.net を使用してオブジェクトをシリアル化します

var Vm = function(data) {
        var self = this;

        ko.mapping.fromJS(data, {}, self);

        self.GetResults = function() {
            $.ajax({
                type: "POST",
                url: '@Url.Action("Action", "Controller")',
                data: ko.mapping.toJSON(self),
                success: function(data) {
                    alert('OK');
                }
            });
        };
    };

    var viewModel = new Vm(@Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model)));
    ko.applyBindings(viewModel);

私の問題は、コントローラーで GetResults アクションを呼び出すと、すべてのプロパティが null になることです。

私のJsonは:

{"Code":"TestCode"}

私は MVC3 プロジェクトで同じ構造を持っており、正常に動作します。MVC4 で何か不足していますか?

乾杯!

4

1 に答える 1

1

いくつかのシナリオでは、jQuery がデータをリクエストのフォームに埋め込むことに気付きました。これが発生すると、値は Controller メソッドのオブジェクト型に自動的にマップされません。

これを回避するには、次の 2 つのことを行う必要があります。

1) データがシリアル化されているかどうかを確認します。これを行う簡単な方法を見つけて、拡張メソッドにダンプしました。

public static class WebContextExtensions
{
    public static bool IsDataSerialized(this HttpContext context)
    {
        return context.Request.Params.AllKeys[0] == null;
    }
}

2) IsDataSerialized が true を返す場合、データをオブジェクト型に逆シリアル化する必要があります。これを行うために、 GenericDeserializer メソッドも作成しました。

public class GenericContextDeserializer<T> where T : new()
{
    public T DeserializeToType(HttpContext context)
    {
        T result = new T();
        if (context != null)
        {
            try
            {
                string jsonString = context.Request.Form.GetValues(0)[0].ToString();
                Newtonsoft.Json.JsonSerializer js = new Newtonsoft.Json.JsonSerializer();
                result = js.Deserialize<T>(new Newtonsoft.Json.JsonTextReader(
                               new System.IO.StringReader(jsonString)));
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        else
            throw new NullReferenceException();
        return result;
    }
}

すべてを Controller メソッドにまとめます。

[HttpPost]
[HttpOptions]
public HttpResponseMessage MyAction(JsonData data)
{
    var results = Request.CreateResponse();
    try
    {
        data = new GenericContextDeserializer<JsonData>().DeserializeToType(HttpContext.Current);
        // do stuff with data
        results.StatusCode = HttpStatusCode.OK;
    }
    catch (Exception ex)
    {
        results.StatusCode = HttpStatusCode.InternalServerError;
    }
    return results;
}

詳細については、私が書いたブログ記事の後半にあります。

于 2013-01-15T14:14:45.823 に答える