2012-10-11 16 views
15

W jaki sposób interfejs Web API może nie deserializować obiektu, który jest deserializowany w JSON.Net?Dlaczego Web Web API nie jest deserializacją, ale JSON.Net będzie?

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

Jest to kontroler 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. 
} 

Jest to JSON, zdobyty przez Skrzypek i sformatowany:

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

Przykładem klasa serializes z JSON.Net ale nie za pomocą kontrolera 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 używa JSON.Net i nie używam żadnych niestandardowych formaterów JSON - po prostu przekazuję JSON do kontrolera Web API. Dlaczego to nie działa?

EDYTOWANIE: Na żądanie, nazywam mojego kontrolera Web API tym JavaScript (część JQuery DataTables). Zauważ, że jestem pewien, że tak samo jest uzyskiwanie JSON do mojego kontrolera niezależnie bo już uchwycił surowy pakiet HTTP z Skrzypek i zapewnił, że jest poprawne:

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

Żądanie HTTP surowy następująco:

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

Proszę napisać jak nazwać swoją metodę webapi (kod js ajax)! – nemesv

+1

Upewnij się, że żądanie ma nagłówek 'Content-Type: application/json' – marcind

+0

@ saturesv: Done. :) –

Odpowiedz

21

Spróbuj usunąć atrybuty [Serializable] ze swoich klas EditorSubmissionMainView i EditorSubmissionMainViewData.

+0

Naprawiono problem. Kontroler teraz deserializuje obiekt. WTH? :) Jak na ironię dodałem "Serializable" w próżnej próbie rozwiązania wcześniejszego problemu. Nadal nie rozumiem, dlaczego JSON.Net może deserializować, gdy jest używany bezpośrednio, ponieważ obiekt jest nadal oznaczony jako "[Serializable]". Dziwne! –

+7

Serialer Json.NET domyślnie ustawia wartość IgnoreSerializableAttribute na true. W WebAPI ustawiamy wartość false. Powodem, dla którego trafiłeś ten problem, jest fakt, że Json.NET ignoruje właściwości: "Json.NET wykrywa teraz typy, które mają SerializableAttribute i serializuje wszystkie pola tego typu, zarówno publiczne, jak i prywatne, i ignoruje właściwości" (cytowane z http: //james.newtonking.com/archive/2012/04/11/json-net-4-5-release-2-serializable-support-and-bug-fixes.aspx) –

+0

@Maggie Ying - Wszelkie pomysły na to pytanie : http://stackoverflow.com/questions/20252027/json-net-web-api-serialization-w-derrived-inherited-types – amcdnl

0

Myślę, że problemem może być użycie "danych" lub "id" w twoim jsonie. Ponieważ musi to przejść przez segregator modelu, może być on zdezorientowany przez zmienną "id" w domyślnej trasie. Lub może być mylony przez ogólny termin "dane", który jest często używany do opisania samego ładunku.

Spróbuj zmienić te nazwy i daj nam znać, jeśli to rozwiązuje.