Come accedere ad un object nidificato da JSON con Json.NET in C #

Come posso selezionare il valore json “EstimateDowndate” all’interno di un object nidificato usando la decorazione di class? La proprietà “estimatedLocationDate” restituisce sempre null invece del valore 2015-10-01T14:00:00.000 . Gli altri valori decorati restituiscono i valori corretti.

Ecco la mia class C#

 public string id { get; set; } public string name { get; set; } [JsonProperty("publishedDate")] public string publishdate { get; set; } [JsonProperty("estimatedLocationDate")] public string estimatedLocationDate{ get; set; } [JsonProperty("createdTime")] public string createtime { get; set; } [JsonProperty("lastUpdatedTime")] public string lastupdate { get; set; } 

E questo è il JSON

 "planet": [ { "id": "123456", "planetid": "en-us/Jupiter-mars/---main", "name": "The planet Mercury", "description": "This is placeholder for the description", "publishedDate": "2013-10-14T23:30:00.000", "createtime": "2012-03-01T14:00:00.000", "product": { "moreid": "1427-48-bd-9-113", "color": "200", "imageUrl": "http://sofit.miximages.com/c%23/images", "neighbor": [ { "ring": "Two", "moons": 2 } ], "estimatedLocationDate": "2014-10-01T14:00:00.000" }, 

Le tue classi dovrebbero assomigliare a questa (anche se questo è incompleto):

 class Planet { [JsonProperty("planet")] PlanetInfo[] planet { get; set; } } class Product { [JsonProperty("estimatedLocationDate")] string estimatedLocationDate {get;set;} } class PlanetInfo { public string id { get; set; } public string name { get; set; } [JsonProperty("publishedDate")] public string publishdate { get; set; } [JsonProperty("estimatedLaunchDate")] public string estimatedLaunchDate { get; set; } [JsonProperty("createdTime")] public string createtime { get; set; } [JsonProperty("lastUpdatedTime")] public string lastupdate { get; set; } [JsonProperty("product")] public Product product { get; set; } } 

Il JSON hai pubblicato non è valido. Puoi convalidare il tuo JSON su JsonLint .

Supponiamo di seguito i tuoi dati JSON .

 { "planet": [ { "id": "123456", "planetid": "en-us/Jupiter-mars/---main", "name": "The planet Mercury", "description": "This is placeholder for the description", "publishedDate": "2013-10-14T23:30:00.000", "createtime": "2012-03-01T14:00:00.000", "product": { "moreid": "1427-48-bd-9-113", "color": "200", "imageUrl": "http://sofit.miximages.com/c%23/images", "neighbor": [ { "ring": "Two", "moons": 2 } ], "estimatedLocationDate": "2014-10-01T14:00:00.000" } } ] } 

Il modo semplice per leggere l’intero JSON è deserialize la gerarchia di classi corretta. Se non lo hai già, puoi creare i seguenti passaggi in Visual Studio

  • Copia i tuoi dati JSON
  • Crea una nuova class vuota in VS
  • VS> Modifica> Incolla speciale> Incolla JSON As Classes

Queste sono le classi generate

 public class PlanetRoot { public Planet[] planet { get; set; } } public class Planet { public string id { get; set; } public string planetid { get; set; } public string name { get; set; } public string description { get; set; } public Product product { get; set; } [JsonProperty("publishedDate")] public string publishdate { get; set; } [JsonProperty("createdTime")] public string createtime { get; set; } } public class Product { public string moreid { get; set; } public string color { get; set; } public string imageUrl { get; set; } public Neighbor[] neighbor { get; set; } public DateTime estimatedLocationDate { get; set; } } public class Neighbor { public string ring { get; set; } public int moons { get; set; } } 

Ora, è facile leggere l’intero object e accedere alla data di assegnazione estimatedLocationDate questo modo

 var jsonString = File.ReadAllText(@"C:\YourDirectory\YourFile.json"); PlanetRoot planet = JsonConvert.DeserializeObject(jsonString); DateTime estimatedLocationDate = planet.planet.First().product.estimatedLocationDate; 

O, se non vuoi leggere l’intero object, puoi leggere direttamente quella proprietà usando Json.NET Linq-to-JSON come questo

 var jObject = JObject.Parse(jsonString); var estLocDate = jObject["planet"][0]["product"]["estimatedLocationDate"].ToObject(); 

Poiché il product rappresenta un altro object, dovrai creare una class per questo:

 public class Planet { public string id { get; set; } public string name { get; set; } [JsonProperty("publishedDate")] public string publishdate { get; set; } [JsonProperty("estimatedLaunchDate")] public string estimatedLaunchDate { get; set; } [JsonProperty("createdTime")] public string createtime { get; set; } [JsonProperty("lastUpdatedTime")] public string lastupdate { get; set; } public Product product { get; set; } } public class Product { public DateTime estimatedLocationDate { get; set; } /* Other members, if necessary */ } string result = JsonConvert.DeserializeObject(jsonString).product.estimatedLocationDate; 

Nota che:

  • Il JSON che hai pubblicato non è valido. Supponiamo di aver copiato non tutto il JSON e di ignorarlo poiché “Gli altri valori decorati restituiscono i valori corretti”.
  • È meglio assegnare i nomi di UpperCamelCase alle proprietà C #

Potresti usare una class interna per il Prodotto ed esporla usando una proprietà come questa.

 public class JsonNet { public static string jsonString = @"{ ""inner"" : { ""name"" : ""myname""}}"; public static Test GetTest() { return JsonConvert.DeserializeObject(jsonString); } } public class Inner { public string Name { get; set; } } public class Test { public Inner Inner { get; set; } public string Name { get { return Inner.Name; } set { Inner.Name = value; } } }