Deserializzazione di JSON utilizzando JSon.NET con dati dinamici

Sto provando a deserializzare alcuni dati JSON in oggetti per un’applicazione. Fino ad ora è andato tutto bene perché le proprietà sui dati JSON erano statiche (chiave con un valore). Ora ho un risultato in cui la chiave è un dato dinamico.

Ecco un esempio di URL JSON:

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

Il JSON risultante per questo è:

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

Ok, è grandioso, tranne che non posso deserializzare i dati delle “pagine” in un object. Se dovessi definire una class per le pagine dovrebbe assomigliare a questa:

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

Per deserializzare il contenuto (usando JsonConvert.Deserialize (jsondata)) e sappiamo tutti che non possiamo avere una class chiamata 6695. Non solo, il nome della class dovrebbe essere diverso (ad esempio pageid = 7145 sarebbe deve essere la class 7145).

Riesco a strappare alcuni valori se uso qualcosa come JObject.Parse (contenuto) e quindi accedere agli elementi come JArrays ma è piuttosto brutto e sono ancora bloccato nel tentativo di estrarre i dati dall’array delle pagine.

Alla ricerca di qualcuno per aiutare con questo. Non penso che sia raro, non sono solo i dati JSON che ho incontrato prima e non sono sicuro di come gestirlo.

Grazie!

PS ha dimenticato di menzionare questo è su Windows Phone 7 così “dinamico” non è disponibile!

Ecco come si utilizza 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}}}}"; 

(Uso dinamico)

 dynamic json = SimpleJson.DeserializeObject(text); string title = json.query.pages["6695"].title; foreach (KeyValuePair page in json.query.pages) { var id = page.Key; var pageId = page.Value.pageid; var ns = page.Value.ns; } 

(Uso di classi fortemente tipizzate)

 class result { public query query { get; set; } } class query { public IDictionary pages { get; set; } } class page { public long pageid { get; set; } public string title { get; set; } } var result = SimpleJson.DeserializeObject(text); 

[Aggiornare]

su windows phone in cui la dynamic non è supportata e non si desidera utilizzare classi fortemente tipizzate.

 var json = (IDictionary)SimpleJson.DeserializeObject(text); var query = (IDictionary)json["query"]; var pages = (IDictionary)query["pages"]; var pageKeys = pages.Keys; var page = (IDictionary)pages["6695"]; var title = (string)page["title"]; 

Il metodo più semplice. In questo caso particolare sarebbe probabilmente di andare dynamic .

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

Puoi fare riferimento a qualsiasi elemento con il suo nome [] modo da poter fare qualcosa come i data["query"]["pages"]["6695"]["lastrevid"] . Ciò otterrà da tutti quei piccoli oggetti in cui il nome non è valido in c #.

Usando Json.net puoi semplicemente fare:

 Dictionary result = JsonConvert.DeserializeObject>(json); foreach(var item in result) Console.WriteLine(item.Key + " " + item.Value); 

Spero che l’esempio sottostante possa aiutarti. Ho sempre progettato un modello che corrisponda al json. È molto meglio lavorare con l’object quando è il tuo modello personale.

È molto facile generare il modello c # da JSON. Utilizzo questo sito Web per generare il modello: http://json2csharp.com

Un esempio completo è:

Codice C #:

  var targetsObject = Newtonsoft.Json.JsonConvert.DeserializeObject(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" } ] } ] } 

Modello:

  public class Program { public string name { get; set; } public string value { get; set; } } public class Investor { public string name { get; set; } public List programs { get; set; } } public class RootObject { public List investors { get; set; } } 

Che ne dici di una semplice ricerca e sostituzione nella stringa JSON? Anche se potrebbe non essere la soluzione più elegante, sarebbe probabilmente la più pragmatica.

Forse potresti semplicemente usare un attributo riservato per contenere il tipo di object e quindi usare il tipo di base come mostrato in questo articolo: Tipi dinamici con JSON.NET