web-dev-qa-db-fra.com

Désérialiser JSON à l'aide de JSon.NET avec des données dynamiques

J'essaie de désérialiser certaines données JSON en objets pour une application. Jusque-là, tout allait bien, car les propriétés des données JSON étaient statiques (clé avec une valeur). Maintenant, j'ai un résultat où la clé est une donnée dynamique.

Voici un exemple d'URL JSON:

http://en.wikipedia.org/w/api.php?action=query&format=json&pageids=6695&prop=info

Le JSON résultant est:

{ "query" : { "pages" : { "6695" : { "counter" : "",
          "lastrevid" : 468683764,
          "length" : 8899,
          "ns" : 0,
          "pageid" : 6695,
          "title" : "Citadel",
          "touched" : "2012-01-03T19:16:16Z"
        } } } }

D'accord, c'est génial, sauf que je ne peux pas désérialiser les données des "pages" dans un objet. Si je devais définir une classe pour les pages, elle devrait ressembler à ceci:

public class 6695
{
    public string counter { get; set; }
    public int lastrevid { get; set; }
    public int length { get; set; }
    public int ns { get; set; }
    public int pageid { get; set; }
    public string title { get; set; }
    public string touched { get; set; }
}

Pour désérialiser le contenu (en utilisant JsonConvert.Deserialize (jsondata)) et nous savons tous que nous ne pouvons pas avoir une classe appelée 6695. De plus, le nom de la classe devrait être différent (par exemple, pageid = 7145 être la classe 7145).

Il peut sembler que j'arrache des valeurs si j'utilise quelque chose comme JObject.Parse (contenu), puis que j'accède aux éléments en tant que JArrays, mais c'est assez moche et je suis toujours bloqué pour essayer d'extraire les données du tableau de pages.

Chercher quelqu'un pour aider avec ceci. Je ne pense pas que ce soit rare, ce ne sont simplement pas des données JSON que j'ai rencontrées auparavant et je ne sais pas comment les gérer.

Merci!

PS a oublié de dire que c'est sur Windows Phone 7, donc "dynamique" n'est pas disponible!

17
Bil Simser

Voici comment vous utilisez https://github.com/facebook-csharp-sdk/simple-json ( https://nuget.org/packages/SimpleJson ).

var text = "{\"query\":{\"pages\":{\"6695\":{\"pageid\":6695,\"ns\":0,\"title\":\"Citadel\",\"touched\":\"2012-01-03T19:16:16Z\",\"lastrevid\":468683764,\"counter\":\"\",\"length\":8899}}}}";

(Utilisation dynamique)

dynamic json = SimpleJson.DeserializeObject(text);
string title = json.query.pages["6695"].title;

foreach (KeyValuePair<string, dynamic> page in json.query.pages)
{
    var id = page.Key;
    var pageId = page.Value.pageid;
    var ns = page.Value.ns;
}

(Utilisation de classes fortement typées)

class result
{
    public query query { get; set; }
}
class query
{
    public IDictionary<string, page> pages { get; set; }
}
class page
{
    public long pageid { get; set; }
    public string title { get; set; }
}

var result = SimpleJson.DeserializeObject<result>(text);

[Mise à jour]

sur Windows Phone où dynamique n'est pas pris en charge et vous ne souhaitez pas utiliser de classes fortement typées.

var json = (IDictionary<string, object>)SimpleJson.DeserializeObject(text);
var query = (IDictionary<string, object>)json["query"];
var pages = (IDictionary<string, object>)query["pages"];
var pageKeys = pages.Keys;
var page = (IDictionary<string, object>)pages["6695"];
var title = (string)page["title"];
18
prabir

La méthode la plus simple. Dans ce cas particulier serait probablement aller dynamic.

dynamic data = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(json);
var lastRevId = data.query.pages["6695"].lastrevid;

Vous pouvez référencer n'importe quel élément par son nom [] afin de pouvoir faire quelque chose comme data["query"]["pages"]["6695"]["lastrevid"]. Cela obtiendra tous ces petits objets dont le nom n'est pas valide en c #.

27
Buildstarted

J'espère que l'exemple ci-dessous aidera. Je conçois toujours un modèle qui correspond au json. Il est bien préférable de travailler avec l'objet lorsqu'il s'agit de votre propre modèle. 

Il est très facile de générer le modèle c # à partir de json. J'utilise ce site pour générer le modèle: http://json2csharp.com

Un exemple complet est:

Code C #:

    var targetsObject = Newtonsoft.Json.JsonConvert.DeserializeObject<YourModel>(jsonString);

JSON:

    {
      "investors": [
        {
          "name": "06",
          "programs": [
            {
              "name": "Conventional",
              "value": "3.5"
            },
            {
              "name": "FHA - Standard",
              "value": "5.0"
            },
            {
              "name": "FHA - Streamline",
              "value": ""
            },
            {
              "name": "VA",
              "value": "5.5"
            },
            {
              "name": "VA IRRRL",
              "value": "6.0"
            },
            {
              "name": "Non-Prime",
              "value": ""
            }
          ]
        },
        {
          "name": "07",
          "programs": [
            {
              "name": "Conventional",
              "value": "3.5"
            },
            {
              "name": "FHA - Standard",
              "value": "5.0"
            },
            {
              "name": "FHA - Streamline",
              "value": "7.0"
            },
            {
              "name": "VA",
              "value": "5.5"
            },
            {
              "name": "VA IRRRL",
              "value": ""
            },
            {
              "name": "Non-Prime",
              "value": ""
            }
          ]
        },
        {
          "name": "08",
          "programs": [
            {
              "name": "Conventional",
              "value": "3.5"
            },
            {
              "name": "FHA - Standard",
              "value": "5.0"
            },
            {
              "name": "FHA - Streamline",
              "value": "7.0"
            },
            {
              "name": "VA",
              "value": "5.5"
            },
            {
              "name": "VA IRRRL",
              "value": ""
            },
            {
              "name": "Non-Prime",
              "value": ""
            }
          ]
        },
        {
          "name": "09",
          "programs": [
            {
              "name": "Conventional",
              "value": "3.5"
            },
            {
              "name": "FHA - Standard",
              "value": "5.0"
            },
            {
              "name": "FHA - Streamline",
              "value": ""
            },
            {
              "name": "VA",
              "value": "5.5"
            },
            {
              "name": "VA IRRRL",
              "value": ""
            },
            {
              "name": "Non-Prime",
              "value": ""
            }
          ]
        },
        {
          "name": "10",
          "programs": [
            {
              "name": "Conventional",
              "value": ""
            },
            {
              "name": "FHA - Standard",
              "value": ""
            },
            {
              "name": "FHA - Streamline",
              "value": ""
            },
            {
              "name": "VA",
              "value": ""
            },
            {
              "name": "VA IRRRL",
              "value": ""
            },
            {
              "name": "Non-Prime",
              "value": "2.0"
            }
          ]
        },
        {
          "name": "11",
          "programs": [
            {
              "name": "Conventional",
              "value": "3.5"
            },
            {
              "name": "FHA - Standard",
              "value": "5.0"
            },
            {
              "name": "FHA - Streamline",
              "value": ""
            },
            {
              "name": "VA",
              "value": "6.0"
            },
            {
              "name": "VA IRRRL",
              "value": "6.0"
            },
            {
              "name": "Non-Prime",
              "value": ""
            }
          ]
        },
        {
          "name": "12",
          "programs": [
            {
              "name": "Conventional",
              "value": "3.5"
            },
            {
              "name": "FHA - Standard",
              "value": "5.0"
            },
            {
              "name": "FHA - Streamline",
              "value": ""
            },
            {
              "name": "VA",
              "value": "5.5"
            },
            {
              "name": "VA IRRRL",
              "value": "6.0"
            },
            {
              "name": "Non-Prime",
              "value": ""
            }
          ]
        },
        {
          "name": "13",
          "programs": [
            {
              "name": "Conventional",
              "value": ""
            },
            {
              "name": "FHA - Standard",
              "value": "5.0"
            },
            {
              "name": "FHA - Streamline",
              "value": ""
            },
            {
              "name": "VA",
              "value": ""
            },
            {
              "name": "VA IRRRL",
              "value": ""
            },
            {
              "name": "Non-Prime",
              "value": "2.0"
            }
          ]
        }
      ]
    }

Modèle:

    public class Program
    {
        public string name { get; set; }
        public string value { get; set; }
    }

    public class Investor
    {
        public string name { get; set; }
        public List<Program> programs { get; set; }
    }

    public class RootObject
    {
        public List<Investor> investors { get; set; }
    }
2
Nour Lababidi

En utilisant Json.net, vous pouvez simplement faire:

Dictionary<string,object> result = JsonConvert.DeserializeObject<Dictionary<string,object>>(json);
foreach(var item in result)
    Console.WriteLine(item.Key + " " + item.Value);
1
mydogisbox

Vous pourriez peut-être simplement utiliser un attribut réservé pour contenir le type d'objet, puis utiliser le type de base comme indiqué dans cet article: Types dynamiques avec JSON.NET

0
vitaly-t

Pourquoi pas une simple recherche et remplacement dans la chaîne JSON? Bien que ce ne soit peut-être pas la solution la plus élégante, ce serait peut-être la plus pragmatique.

0
Tom