webentwicklung-frage-antwort-db.com.de

Deserialisierung des JSON-Arrays in ein stark typisiertes .NET-Objekt

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

29
Matt Lacey

versuchen

List<TheUser> friends = jsonSerializer.Deserialize<List<TheUser>>(response);
11
Frank

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();
} 
7
Erick Brown

Dies funktionierte für mich, um JSON in ein Array von Objekten zu deserialisieren:

List<TheUser> friends = JsonConvert.DeserializeObject<List<TheUser>>(response);
7
Homer

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();
6
bobah75

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

2
AwkwardCoder

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; }
}
0
Nigel Sampson