0

当我尝试将 json 反序列化为 MVC4 中的对象时遇到问题。

我有一个视图模型:

 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 操作时,所有属性都为空。

我的Json是:

{"Code":"TestCode"}

我在 MVC3 项目中具有相同的结构并且工作正常。我在 MVC4 中遗漏了什么?

干杯!

4

1 回答 1

1

我们注意到,在某些情况下,jQuery 会将数据嵌入到请求中的表单中。发生这种情况时,值不会自动映射到 Controller 方法中的对象类型。

为了解决这个问题,你需要做两件事:

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 回答