Deserializar datos JSON a C # usando JSON.NET

Soy relativamente nuevo en el trabajo con datos C # y JSON y busco orientación. Estoy usando C # 3.0, con .NET3.5SP1 y JSON.NET 3.5r6.

Tengo una clase C # definida que necesito completar de una estructura JSON. Sin embargo, no todas las estructuras JSON para una entrada que se recupera del servicio web contienen todos los atributos posibles que se definen dentro de la clase C #.

He estado haciendo lo que parece ser el camino equivocado, difícil y simplemente seleccionando cada valor del JObject y transformando la cadena en la propiedad de clase deseada.

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

¿Cuál es la mejor manera de deserializar una estructura JSON en la clase C # y manejar posibles datos faltantes de la fuente JSON?

Mi clase se define como:

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

Y una muestra de JSON para analizar es:

 { "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" ] } 

Utilice JsonConvert.DeserializeObject(string json);

Crea tus clases en JSON 2 C #


Documentación de Json.NET: serialización y deserialización de JSON con Json.NET

¿Has intentado utilizar el método genérico DeserializeObject?

 JsonConvert.DeserializeObject(myjsondata); 

Cualquier campo faltante en los datos JSON simplemente debe dejarse NULO.

ACTUALIZAR:

Si la cadena JSON es una matriz, intente esto:

 var jarray = JsonConvert.DeserializeObject>(myjsondata); 

jarray debería ser una List .

OTRA ACTUALIZACIÓN:

La excepción que recibe no es coherente con una matriz de objetos: creo que el serializador tiene problemas con la propiedad de estado de accountstatusmodifiedby escrita por diccionario.

Intente excluir la propiedad accountstatusmodifiedby de la serialización y vea si eso ayuda. Si lo hace, es posible que deba representar esa propiedad de manera diferente.

Documentación: serializar y deserializar JSON con Json.NET

Respuesta reproducida de https://stackoverflow.com/a/10718128/776476

Puede usar el tipo dynamic C # para facilitar las cosas. Esta técnica también simplifica el refaccionamiento, ya que no depende de cadenas mágicas.

Json

La cadena json continuación es una respuesta simple de una llamada http api y define dos propiedades: Id y Name .

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

DO#

Utilice JsonConvert.DeserializeObject() para deserializar esta cadena en un tipo dynamic y luego simplemente acceda a sus propiedades de la forma habitual.

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

Nota : El enlace NuGet para el ensamblaje de NewtonSoft es http://nuget.org/packages/newtonsoft.json . No olvides agregar: using Newtonsoft.Json; para acceder a esas clases

Puedes usar:

 JsonConvert.PopulateObject(json, obj); 

aquí: json es la cadena json, obj es el objeto objective. Ver: ejemplo

Nota: PopulateObject() no borrará los datos de la lista obj, después de que Populate() , obj's miembro de obj's lista obj's contendrá sus datos originales y datos de la cadena json.

Partiendo de la respuesta de bbant, esta es mi solución completa para deserializar JSON desde una URL remota.

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

El uso sería como:

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

Donde FeedResult es la clase generada usando el generador de clases Xamasoft JSON

Aquí hay una captura de pantalla de la configuración que utilicé, lo que permite nombres de propiedades raras que la versión web no podía explicar.

Generador de clases Xamasoft JSON

Puede intentar consultar algunos de los generadores de clases en línea para obtener más información. Sin embargo, creo que algunas de las respuestas han sido útiles. Aquí está mi enfoque que puede ser útil.

El siguiente código fue hecho con un método dynamic en 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"]); } } 

Este código básicamente le permite acceder a los miembros contenidos en la cadena Json. Solo de una manera diferente sin la necesidad de las clases. query , trend y url son los objetos contenidos en la cadena Json.

También puedes usar este sitio web . No confíes en las clases al 100% pero entiendes la idea.

Encontré que había construido mi objeto incorrectamente. Usé http://json2csharp.com/ para generar mi clase de objeto desde JSON. Una vez que tuve el objeto correcto, pude lanzar sin problemas. Norbit, error novato. Pensé que lo agregaría en caso de que tenga el mismo problema.

Suponiendo que sus datos de muestra son correctos, su nombre de stack y otras entradas entre paréntesis son matrices en JS … querrá usar List para esos tipos de datos. y List for say accountstatusexpmaxdate … Creo que su ejemplo tiene las fechas incorrectamente formateadas, por lo que no está seguro de qué más es incorrecto en su ejemplo.

Esta es una publicación anterior, pero quería tomar nota de los problemas.