2012-10-11 109 views
15

Web API如何無法反序列化JSON.Net反序列化的對象?爲什麼Web API並不反序列化這個,但JSON.Net會?

Visual Studio showing Web API's attempt as all nulls but JSON.Net's properly populated

這是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. 
} 

這是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是找我的控制器不管,因爲我已經捕獲與小提琴手的原始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":""}} 
+0

請發表您如何打電話給您的webapi方法(js ajax代碼)! – nemesv

+1

確保您的請求具有'Content-Type:application/json'標頭 – marcind

+0

@nemesv:完成。 :) –

回答

21

嘗試從您的類EditorSubmissionMainView和EditorSubmissionMainViewData中移除[Serializable]屬性。

+0

解決了這個問題。控制器現在反序列化對象。 WTH? :) 具有諷刺意味的是我添加了'[Serializable]'妄圖解決早期的問題。我仍然不明白爲什麼JSON.Net直接使用時可以反序列化,因爲對象仍然使用'[Serializable]'標記。奇怪! –

+7

Json.NET序列化程序默認將IgnoreSerializableAttribute設置爲true。在WebAPI中,我們將其設置爲false。之所以出現這個問題是因爲Json.NET忽略了屬性:「Json.NET現在檢測到具有Seri​​alizableAttribute的類型,並序列化該類型的所有字段,包括public和private,並忽略這些屬性」(引自http: //james.newtonking.com/archive/2012/04/11/json-net-4-5-release-2-serializable-support-and-bug-fixes.aspx) –

+0

@Maggie Ying - 對這個問題的任何想法:http://stackoverflow.com/questions/20252027/json-net-web-api-serialization-with-derrived-inherited-types – amcdnl

0

我認爲這個問題可能是在你的json中使用「data」或「id」。因爲這必須通過模型綁定器,它可能會被默認路由中的「id」變量弄糊塗。或者,它可能會被通常用於描述有效載荷本身的通用術語「數據」所困惑。

嘗試更改這些名稱,讓我們知道如果解決了它。