web-dev-qa-db-fra.com

Désérialisation du tableau JSON en objet .NET fortement typé

Quand je peux appeler l'API tierce et récupérer une seule classe de données, tout se désérialise bien en utilisant ce code

TheUser me = jsonSerializer.Deserialize(response, typeof(TheUser)) as TheUser

Le problème survient lorsque j'essaie de désérialiser le contenu de la réponse JSON qui est un tableau, tel que

{
   "data": [
      {
         "name": "A Jones",
         "id": "500015763"
      },
      {
         "name": "B Smith",
         "id": "504986213"
      },
      {
         "name": "C Brown",
         "id": "509034361"
      }
   ]
}

Je ne peux faire fonctionner la sérialisation que si j'utilise une classe d'habillage personnalisée autour du membre "data" et que ce membre doit être de type List<object>. S'il les a comme type List<TheUser> Je reçois ArgumentException du JsonParser DesializeType méthode.

J'ai à l'origine essayé de sérialiser sans type d'emballage comme celui-ci

List<TheUser> freinds = jsonSerializer.Deserialize(response, typeof(List<TheUser>)) as List<TheUser>;

mais cela me renvoie juste une collection vide. Je dois sûrement être capable de désérialiser le tableau en une liste fortement typée.

Après avoir regardé la source , pour WP7 Hammock n'utilise pas réellement Json.Net pour l'analyse JSON. Au lieu de cela, il utilise son propre analyseur qui ne gère pas très bien les types personnalisés.

Si vous utilisez Json.Net directement, il est possible de désérialiser vers une collection fortement typée à l'intérieur d'un objet wrapper.

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

et avec:

public class MyClass
{
    public List<User> data { get; set; }
}

public class User
{
    public string name { get; set; }
    public string id { get; set; }
}

Devoir créer l'objet supplémentaire avec la propriété data est ennuyeux mais c'est une conséquence de la façon dont l'objet formaté JSON est construit.

Documentation: Sérialisation et désérialisation JSON

29
Matt Lacey

essayer

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

Cette solution semble fonctionner pour moi et contourne d'avoir à coder un tas de classes avec "Data" en eux.

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

J'aurais dû inclure cela pour commencer, voici un exemple de méthode utilisant ce qui précède:

public List<TheUser> GetUser()
{
    var results = GetUserJson();
    var userList = JsonConvert.DeserializeObject<DataResponse<TheUser>>(results.ToString());

    return userList.Data.ToList();
} 
7
Erick Brown

Cela a fonctionné pour moi pour désérialiser JSON en un tableau d'objets:

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

Json.NET - Documentation

http://james.newtonking.com/json/help/index.html?topic=html/SelectToken.htm

Interprétation pour l'auteur

var o = JObject.Parse(response);
var a = o.SelectToken("data").Select(jt => jt.ToObject<TheUser>()).ToList();
6
bobah75

Pat, la structure json semble très familière à un problème que j'ai décrit ici - La réponse pour moi était de traiter la représentation json comme un dictionnaire <TKey, TValue>, même s'il n'y avait qu'une seule entrée.

Si j'ai raison, votre clé est de type chaîne et la valeur d'une liste <T> où T représente la classe 'TheUser'

HTH

PS - si vous voulez une meilleure vérification de la perf de sérialisation en utilisant Silverlight Serializer , vous aurez besoin de construire une version WP7, Shameless plug - j'ai écrit un article de blog sur this

2
AwkwardCoder

Je soupçonne que le problème est dû au fait que le json représente un objet avec la liste des utilisateurs en tant que propriété. Essayez de désérialiser en quelque chose comme:

public class UsersResponse
{
    public List<User> Data { get; set; }
}
0
Nigel Sampson