Wenn ich die API eines Drittanbieters aufrufen und eine einzelne Datenklasse zurückerhalten kann, wird alles mit diesem Code in Ordnung deserialisiert
TheUser me = jsonSerializer.Deserialize(response, typeof(TheUser)) as TheUser
Das Problem tritt auf, wenn ich versuche, JSON-Antwortinhalte zu deserialisieren, die ein Array sind, z
{
"data": [
{
"name": "A Jones",
"id": "500015763"
},
{
"name": "B Smith",
"id": "504986213"
},
{
"name": "C Brown",
"id": "509034361"
}
]
}
Ich kann die Serialisierung nur zum Laufen bringen, wenn ich eine benutzerdefinierte Wrapping-Klasse um das Member "data" verwende und dieses Member vom Typ List<object>
Sein muss. Wenn sie den Typ List<TheUser>
Haben, erhalte ich ArgumentException
von der Methode JsonParser DesializeType
.
Ich habe ursprünglich versucht, ohne einen solchen Verpackungstyp zu serialisieren
List<TheUser> freinds = jsonSerializer.Deserialize(response, typeof(List<TheUser>)) as List<TheUser>;
aber das gibt mir nur eine leere sammlung zurück. Sicher muss ich in der Lage sein, das Array zu einer stark typisierten Liste deserialisieren zu lassen.
Wenn Sie sich die Quelle ansehen, verwendet WP7 Hammock Json.Net nicht für die JSON-Analyse. Stattdessen wird ein eigener Parser verwendet, der mit benutzerdefinierten Typen nicht sehr gut zurechtkommt.
Wenn Sie Json.Net direkt verwenden, ist es möglich, eine Deserialisierung zu einer stark typisierten Auflistung innerhalb eines Wrapper-Objekts durchzuführen.
var response = @"
{
""data"": [
{
""name"": ""A Jones"",
""id"": ""500015763""
},
{
""name"": ""B Smith"",
""id"": ""504986213""
},
{
""name"": ""C Brown"",
""id"": ""509034361""
}
]
}
";
var des = (MyClass)Newtonsoft.Json.JsonConvert.DeserializeObject(response, typeof(MyClass));
return des.data.Count.ToString();
und mit:
public class MyClass
{
public List<User> data { get; set; }
}
public class User
{
public string name { get; set; }
public string id { get; set; }
}
Es ist ärgerlich, das zusätzliche Objekt mit der data -Eigenschaft erstellen zu müssen. Dies ist jedoch eine Folge der Art und Weise, wie das JSON-formatierte Objekt erstellt wird.
Dokumentation: JSON serialisieren und deserialisieren
versuchen
List<TheUser> friends = jsonSerializer.Deserialize<List<TheUser>>(response);
Diese Lösung scheint für mich zu funktionieren und umgeht die Notwendigkeit, eine Reihe von Klassen mit "Data" zu codieren.
public interface IDataResponse<T> where T : class
{
List<T> Data { get; set; }
}
public class DataResponse<T> : IDataResponse<T> where T : class
{
[JsonProperty("data")]
public List<T> Data { get; set; }
}
Ich hätte dies zu Beginn einschließen sollen. Hier ist eine Beispielmethode, die das Obige verwendet:
public List<TheUser> GetUser()
{
var results = GetUserJson();
var userList = JsonConvert.DeserializeObject<DataResponse<TheUser>>(results.ToString());
return userList.Data.ToList();
}
Dies funktionierte für mich, um JSON in ein Array von Objekten zu deserialisieren:
List<TheUser> friends = JsonConvert.DeserializeObject<List<TheUser>>(response);
Json.NET - Dokumentation
http://james.newtonking.com/json/help/index.html?topic=html/SelectToken.htm
Interpretation für den Autor
var o = JObject.Parse(response);
var a = o.SelectToken("data").Select(jt => jt.ToObject<TheUser>()).ToList();
Pat, die json-Struktur kommt einem von mir beschriebenen Problem sehr bekannt vor hier - Die Antwort für mich war, die json-Darstellung als Dictionary <TKey, TValue> zu behandeln, obwohl es nur 1 Eintrag gab.
Wenn ich richtig bin, ist Ihr Schlüssel vom Typ string und der Wert einer Liste <T>, wobei T die Klasse 'TheUser' darstellt.
HTH
PS - wenn Sie eine bessere Serialisierung für das Auschecken mit Silverlight Serializer wünschen, müssen Sie eine WP7-Version erstellen, Shameless Plug - ich habe einen Blog-Beitrag über this geschrieben
Ich vermute, das Problem liegt daran, dass der json ein Objekt mit der Liste der Benutzer als Eigenschaft darstellt. Versuchen Sie es mit einer Deserialisierung wie:
public class UsersResponse
{
public List<User> Data { get; set; }
}