【问题标题】:Why won't Web API deserialize this but JSON.Net will?为什么 Web API 不会反序列化,但 JSON.Net 会?
【发布时间】:2012-10-02 09:04:25
【问题描述】:

Web API 如何无法反序列化 JSON.Net 反序列化的对象?

这是 Web API 控制器:

public void Put(EditorSubmissionMainView ajaxSubmission) {
// ajaxSubmission: EditorSubmissionMainView with all values ('data' also == null)

    string json = "{\"id\":\"row_1377\",\"data\":{\"ROTATION\":\"1\",\"EQUIPMENT\":[{\"id\":\"6\"},{\"id\":\"8\"}],\"NOTES\":\"\"}}";

    EditorSubmissionMainView foo = Newtonsoft.Json.JsonConvert.DeserializeObject<EditorSubmissionMainView>(json) as EditorSubmissionMainView;
// foo is a EditorSubmissionMainView but properly deserialized.
}

这是 Fiddler 捕获并格式化的 JSON:

{
    "id": "row_1377",
    "data": {
        "ROTATION": "1",
        "EQUIPMENT": [{
            "id": "6"
        },
        {
            "id": "8"
        }],
        "NOTES": ""
    }
}

使用 JSON.Net 但不使用 Web API 控制器序列化的示例类:

[Serializable]
public class EditorSubmissionMainView
{
    public string id { get; set; }
    public EditorSubmissionMainViewData data { get; set; }
}

[Serializable]
public class EditorSubmissionMainViewData
{
    [JsonProperty("ROTATION")]
    public int? rotation { get; set; } // Same problem if everything is a string

    [JsonProperty("EQUIPMENT")]
    public ICollection<Dictionary<string, int?>> equipment { get; set; }

    [JsonProperty("NOTES")]
    public string notes { get; set; }
}

Web API 使用 JSON.Net,我没有使用任何自定义 JSON 格式化程序——只是将 JSON 传递给 Web API 控制器。为什么这不起作用?

编辑: 根据要求,我正在使用这个 Javascript(JQuery DataTables 的一部分)调用我的 Web API 控制器。请注意,我确信相同的 JSON 会到达我的控制器,因为我已经使用 Fiddler 捕获了原始 HTTP 数据包并确保它是正确的:

"ajaxUrl": {
    "create": "POST @Url.Content("~/API/MainView")",
    "edit":   "PUT @Url.Content("~/API/MainView")",
    "remove": "DELETE @Url.Content("~/API/MainView")"
},

"ajax": function (method, url, data, successCallback, errorCallback) {
    $.ajax({
        "type": method,
        "url": url,
        "data": JSON.stringify(data), // Requires IE8+
        "contentType": "application/json",
        "dataType": "json",
        "success": function (json) {
            successCallback(json);
        },
        "error": function (xhr, error, thrown) {
            errorCallback(xhr, error, thrown);
        }
    });
},

原始 HTTP 请求如下:

PUT http://localhost:53367/API/MainView HTTP/1.1
x-requested-with: XMLHttpRequest
Accept-Language: en-us
Referer: http://localhost:53367/Manage/MainView
Accept: application/json, text/javascript, */*; q=0.01
Content-Type: application/json
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Host: localhost:53367
Content-Length: 306
Connection: Keep-Alive
Pragma: no-cache
Cookie: ASP.NET_SessionId=wqsghjrol20cszrxfzdm0qo4

{"id":"row_1377","data":{"ROTATION":"1","EQUIPMENT":[{"id":"6"},{"id":"8"}],"NOTES":""}}

【问题讨论】:

  • 请发布您如何调用您的 webapi 方法(js ajax 代码)!
  • 确保您的请求具有Content-Type: application/json 标头
  • WebAPI 返回什么?
  • @MerickOWA:在控制器中,ajaxSubmission 显示为具有所有属性的EditorSubmissionMainView,但它们都是null
  • @marcind:我以前肯定遇到过这个问题!在这种情况下,虽然我只是发布了内容类型确实正确的原始 HTTP 请求。

标签: c# asp.net-mvc asp.net-web-api json.net


【解决方案1】:

尝试从类 EditorSubmissionMainView 和 EditorSubmissionMainViewData 中删除 [Serializable] 属性。

【讨论】:

  • 解决了这个问题。控制器现在反序列化对象。什么? :) 具有讽刺意味的是,我添加了[Serializable] 以试图解决早期的问题,但这是徒劳的。我还是不明白为什么直接使用 JSON.Net 可以反序列化,因为对象仍然用[Serializable] 标记。奇怪!
  • Json.NET 序列化程序默认将 IgnoreSerializableAttribute 设置为 true。在 WebAPI 中,我们将其设置为 false。您遇到此问题的原因是因为 Json.NET 忽略了属性:“Json.NET 现在检测具有 SerializableAttribute 的类型并序列化该类型的所有字段,包括公共和私有,并忽略属性”(引自 @987654321 @)
  • @Maggie Ying - 关于这个问题的任何想法:stackoverflow.com/questions/20252027/…
  • 检查我的问题以使 JSON.NET 和 [Serializable] 一起工作:stackoverflow.com/questions/20914080/…
【解决方案2】:

我认为问题可能是在您的 json 中使用了“data”或“id”。因为这必须通过模型绑定器,所以它可能会被默认路由中的“id”变量混淆。或者,它可能会被通常用于描述有效负载本身的通用术语“数据”混淆。

尝试更改这些名称并告诉我们是否可以解决问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-24
    • 1970-01-01
    • 2012-09-05
    • 1970-01-01
    • 2020-10-19
    • 2013-03-05
    • 2020-06-08
    相关资源
    最近更新 更多