2012-10-11 31 views
15

Làm thế nào Web API có thể không deserialize một đối tượng mà JSON.Net deserializes?Tại sao API Web không deserialize này nhưng JSON.Net sẽ?

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

Đây là bộ điều khiển 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. 
} 

Đây là JSON, bị bắt bởi Fiddler và định dạng:

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

Một lớp ví dụ mà serializes với JSON.Net nhưng không phải với bộ điều khiển API Web:

[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; } 
} 

API Web sử dụng JSON.Net và tôi không sử dụng bất kỳ trình định dạng JSON tùy chỉnh nào - chỉ cần chuyển JSON sang bộ điều khiển API Web. Tại sao cái này không hoạt động?

EDIT: Theo yêu cầu, tôi đang gọi bộ điều khiển API Web của tôi với Javascript này (một phần của JQuery DataTables). Lưu ý rằng tôi chắc chắn cùng JSON là nhận được để điều khiển của tôi bất kể vì tôi đã bắt các gói tin HTTP liệu với Fiddler và đảm bảo rằng nó là đúng:

"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); 
     } 
    }); 
}, 

Yêu cầu HTTP liệu sau:

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

Vui lòng đăng cách bạn gọi phương thức webapi của mình (mã js ajax)! – nemesv

+1

Đảm bảo yêu cầu của bạn có tiêu đề 'Content-Type: application/json' – marcind

+0

@nemesv: Xong. :) –

Trả lời

21

Thử xóa thuộc tính [Serializable] khỏi lớp EditorSubmissionMainView và EditorSubmissionMainViewData của bạn.

+0

Điều đó đã khắc phục được sự cố. Bộ điều khiển bây giờ deserializes đối tượng. WTH? :) Trớ trêu thay tôi đã thêm '[Serializable]' vào một nỗ lực vô ích để giải quyết một vấn đề trước đó. Tôi vẫn không hiểu tại sao JSON.Net có thể deserialize khi được sử dụng trực tiếp bởi vì đối tượng vẫn được gắn thẻ với '[Serializable]'. Lạ thật! –

+7

Bộ nối tiếp Json.NET theo mặc định đặt IgnoreSerializableAttribute thành true. Trong WebAPI, chúng ta đặt nó thành false. Lý do tại sao bạn nhấn vấn đề này là bởi vì Json.NET bỏ qua các thuộc tính: "Json.NET bây giờ phát hiện các loại có SerializableAttribute và tuần tự hóa tất cả các trường trên loại đó, cả công khai và riêng tư, và bỏ qua các thuộc tính" (được trích dẫn từ http: //james.newtonking.com/archive/2012/04/11/json-net-4-5-release-2-serializable-support-and-bug-fixes.aspx) –

+0

@Maggie Ying - Bất kỳ ý tưởng nào về câu hỏi này : http://stackoverflow.com/questions/20252027/json-net-web-api-serialization-with-derrived-inherited-types – amcdnl

0

Tôi nghĩ rằng vấn đề có thể là việc sử dụng "dữ liệu" hoặc "id" trong json của bạn. Bởi vì điều này đã đi qua mô hình chất kết dính, nó có thể bị nhầm lẫn bởi biến "id" trong tuyến đường mặc định. Hoặc, nó có thể bị nhầm lẫn bởi thuật ngữ chung "dữ liệu" thường được sử dụng để mô tả chính tải trọng đó.

Hãy thử thay đổi các tên này và cho chúng tôi biết nếu điều đó giải quyết được.

Các vấn đề liên quan