Deserializzazione dei dati JSON in C # utilizzando JSON.NET

Sono relativamente nuovo a lavorare con i dati C # e JSON e sto cercando una guida. Sto usando C # 3.0, con .NET3.5SP1 e JSON.NET 3.5r6.

Ho una class C # definita che ho bisogno di compilare da una struttura JSON. Tuttavia, non tutte le strutture JSON per una voce recuperate dal servizio Web contengono tutti gli attributi possibili definiti nella class C #.

Sto facendo quello che sembra essere il modo sbagliato, difficile e basta individuare ogni valore uno per uno dal JObject e trasformare la stringa nella proprietà di class desiderata.

JsonSerializer serializer = new JsonSerializer(); var o = (JObject)serializer.Deserialize(myjsondata); MyAccount.EmployeeID = (string)o["employeeid"][0]; 

Qual è il modo migliore per deserializzare una struttura JSON nella class C # e gestire possibili dati mancanti dall’origine JSON?

La mia class è definita come:

  public class MyAccount { [JsonProperty(PropertyName = "username")] public string UserID { get; set; } [JsonProperty(PropertyName = "givenname")] public string GivenName { get; set; } [JsonProperty(PropertyName = "sn")] public string Surname { get; set; } [JsonProperty(PropertyName = "passwordexpired")] public DateTime PasswordExpire { get; set; } [JsonProperty(PropertyName = "primaryaffiliation")] public string PrimaryAffiliation { get; set; } [JsonProperty(PropertyName = "affiliation")] public string[] Affiliation { get; set; } [JsonProperty(PropertyName = "affiliationstatus")] public string AffiliationStatus { get; set; } [JsonProperty(PropertyName = "affiliationmodifytimestamp")] public DateTime AffiliationLastModified { get; set; } [JsonProperty(PropertyName = "employeeid")] public string EmployeeID { get; set; } [JsonProperty(PropertyName = "accountstatus")] public string AccountStatus { get; set; } [JsonProperty(PropertyName = "accountstatusexpiration")] public DateTime AccountStatusExpiration { get; set; } [JsonProperty(PropertyName = "accountstatusexpmaxdate")] public DateTime AccountStatusExpirationMaxDate { get; set; } [JsonProperty(PropertyName = "accountstatusmodifytimestamp")] public DateTime AccountStatusModified { get; set; } [JsonProperty(PropertyName = "accountstatusexpnotice")] public string AccountStatusExpNotice { get; set; } [JsonProperty(PropertyName = "accountstatusmodifiedby")] public Dictionary AccountStatusModifiedBy { get; set; } [JsonProperty(PropertyName = "entrycreatedate")] public DateTime EntryCreatedate { get; set; } [JsonProperty(PropertyName = "entrydeactivationdate")] public DateTime EntryDeactivationDate { get; set; } } 

E un esempio del JSON da analizzare è:

 { "givenname": [ "Robert" ], "passwordexpired": "20091031041550Z", "accountstatus": [ "active" ], "accountstatusexpiration": [ "20100612000000Z" ], "accountstatusexpmaxdate": [ "20110410000000Z" ], "accountstatusmodifiedby": { "20100214173242Z": "tdecker", "20100304003242Z": "jsmith", "20100324103242Z": "jsmith", "20100325000005Z": "rjones", "20100326210634Z": "jsmith", "20100326211130Z": "jsmith" }, "accountstatusmodifytimestamp": [ "20100312001213Z" ], "affiliation": [ "Employee", "Contractor", "Staff" ], "affiliationmodifytimestamp": [ "20100312001213Z" ], "affiliationstatus": [ "detached" ], "entrycreatedate": [ "20000922072747Z" ], "username": [ "rjohnson" ], "primaryaffiliation": [ "Staff" ], "employeeid": [ "999777666" ], "sn": [ "Johnson" ] } 

Usa JsonConvert.DeserializeObject(string json);

Crea le tue lezioni su JSON 2 C #


Documentazione Json.NET: serializzazione e deserializzazione di JSON con Json.NET

Hai provato a utilizzare il metodo generico DeserializeObject?

 JsonConvert.DeserializeObject(myjsondata); 

Tutti i campi mancanti nei dati JSON devono essere semplicemente lasciati NULL.

AGGIORNARE:

Se la stringa JSON è una matrice, prova questo:

 var jarray = JsonConvert.DeserializeObject>(myjsondata); 

jarray dovrebbe quindi essere una List .

UN ALTRO AGGIORNAMENTO:

L’eccezione che si ottiene non è coerente con una serie di oggetti: penso che il serializzatore stia riscontrando problemi con la proprietà accounttatusmodifiedby tipizzata dal dizionario.

Provare ad escludere la proprietà accountstatusmodifiedby dalla serializzazione e vedere se questo aiuta. Se lo fa, potresti dover rappresentare questa proprietà in modo diverso.

Documentazione: serializzazione e deserializzazione di JSON con Json.NET

Risposta riprodotta da https://stackoverflow.com/a/10718128/776476

Puoi usare il tipo dynamic C # per semplificare le cose. Questa tecnica rende anche il ri-factoring più semplice in quanto non si basa su stringhe magiche.

jSON

La stringa json qui sotto è una semplice risposta da una chiamata http api e definisce due proprietà: Id e Name .

 {"Id": 1, "Name": "biofractal"} 

C #

Usa JsonConvert.DeserializeObject() per deserializzare questa stringa in un tipo dinamico, quindi accedi semplicemente alle sue proprietà nel solito modo.

 var results = JsonConvert.DeserializeObject(json); var id = results.Id; var name= results.Name; 

Nota : il collegamento NuGet per l’assembly NewtonSoft è http://nuget.org/packages/newtonsoft.json . Non dimenticare di aggiungere: using Newtonsoft.Json; per accedere a quelle classi.

Puoi usare:

 JsonConvert.PopulateObject(json, obj); 

qui: json è la stringa json, obj è l’object target. Vedi: esempio

Nota: PopulateObject() non cancellerà i dati dell’elenco di oggetti, dopo Populate() , obj's membro dell’elenco obj's conterrà i suoi dati e dati originali dalla stringa json

Partendo dalla risposta di bbant, questa è la mia soluzione completa per deserializzare JSON da un URL remoto.

 using Newtonsoft.Json; using System.Net.Http; namespace Base { public class ApiConsumer { public T data; private string url; public CalendarApiConsumer(string url) { this.url = url; this.data = getItems(); } private T getItems() { T result = default(T); HttpClient client = new HttpClient(); // This allows for debugging possible JSON issues var settings = new JsonSerializerSettings { Error = (sender, args) => { if (System.Diagnostics.Debugger.IsAttached) { System.Diagnostics.Debugger.Break(); } } }; using (HttpResponseMessage response = client.GetAsync(this.url).Result) { if (response.IsSuccessStatusCode) { result = JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().Result, settings); } } return result; } } } 

L’utilizzo sarebbe come:

 ApiConsumer feed = new ApiConsumer("http://example.info/feeds/feeds.aspx?alt=json-in-script"); 

Dove FeedResult è la class generata utilizzando il generatore di classi JSON di Xamasoft

Ecco uno screenshot delle impostazioni che ho usato, tenendo conto dei nomi di proprietà strani che la versione web non poteva tenere conto.

Xamasoft JSON Class Generator

Puoi provare a controllare alcuni generatori di classi online per ulteriori informazioni. Tuttavia, credo che alcune delle risposte siano state utili. Ecco il mio approccio che potrebbe essere utile.

Il seguente codice è stato creato con un metodo dinamico in mente.

 dynObj = (JArray)JsonConvert.DeserializeObject(nvm); foreach (JObject item in dynObj) { foreach (JObject trend in item["trends"]) { Console.WriteLine("{0}-{1}-{2}", trend["query"], trend["name"], trend["url"]); } } 

Questo codice consente fondamentalmente di accedere ai membri contenuti nella stringa Json. Solo in un modo diverso senza bisogno delle classi. query , trend e url sono gli oggetti contenuti nella stringa Json.

Puoi anche usare questo sito web . Non fidarti delle classi al 100% ma ottieni l’idea.

Ho trovato che avevo costruito il mio object in modo errato. Ho usato http://json2csharp.com/ per generare la mia class object da JSON. Una volta ottenuto il corretto Oject, sono riuscito a eseguire il cast senza problemi. Norbit, errore di Noob. Ho pensato di aggiungerlo nel caso avessi lo stesso problema.

Supponendo che i dati del campione siano corretti, il tuo givenname e le altre voci racchiuse tra parentesi sono matrici in JS … ti consigliamo di utilizzare Elenco per questi tipi di dati. ed Elenco per dire accountstatusexpmaxdate … Penso che per esempio le date siano state formattate in modo errato, quindi incerto su cosa altro non è corretto nell’esempio.

Questo è un vecchio post, ma volevo prendere nota dei problemi.