Deserializar JSON en C # objeto dynamic?

¿Hay alguna forma de deserializar el contenido JSON en un tipo dynamic C # 4? Sería bueno omitir la creación de un grupo de clases para utilizar DataContractJsonSerializer.

Si está contento de tener una dependencia en el ensamblado System.Web.Helpers , puede usar la clase Json :

 dynamic data = Json.Decode(json); 

Se incluye con el marco MVC como una descarga adicional para .NET 4 framework. Asegúrate de darle a Vlad un voto positivo si eso es útil. Sin embargo, si no puede suponer que el entorno del cliente incluye esta DLL, siga leyendo.


Aquí se sugiere un enfoque de deserialización alternativo. Modifiqué el código ligeramente para corregir un error y adaptarme a mi estilo de encoding. Todo lo que necesita es este código y una referencia a System.Web.Extensions de su proyecto:

 using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Dynamic; using System.Linq; using System.Text; using System.Web.Script.Serialization; public sealed class DynamicJsonConverter : JavaScriptConverter { public override object Deserialize(IDictionary dictionary, Type type, JavaScriptSerializer serializer) { if (dictionary == null) throw new ArgumentNullException("dictionary"); return type == typeof(object) ? new DynamicJsonObject(dictionary) : null; } public override IDictionary Serialize(object obj, JavaScriptSerializer serializer) { throw new NotImplementedException(); } public override IEnumerable SupportedTypes { get { return new ReadOnlyCollection(new List(new[] { typeof(object) })); } } #region Nested type: DynamicJsonObject private sealed class DynamicJsonObject : DynamicObject { private readonly IDictionary _dictionary; public DynamicJsonObject(IDictionary dictionary) { if (dictionary == null) throw new ArgumentNullException("dictionary"); _dictionary = dictionary; } public override string ToString() { var sb = new StringBuilder("{"); ToString(sb); return sb.ToString(); } private void ToString(StringBuilder sb) { var firstInDictionary = true; foreach (var pair in _dictionary) { if (!firstInDictionary) sb.Append(","); firstInDictionary = false; var value = pair.Value; var name = pair.Key; if (value is string) { sb.AppendFormat("{0}:\"{1}\"", name, value); } else if (value is IDictionary) { new DynamicJsonObject((IDictionary)value).ToString(sb); } else if (value is ArrayList) { sb.Append(name + ":["); var firstInArray = true; foreach (var arrayValue in (ArrayList)value) { if (!firstInArray) sb.Append(","); firstInArray = false; if (arrayValue is IDictionary) new DynamicJsonObject((IDictionary)arrayValue).ToString(sb); else if (arrayValue is string) sb.AppendFormat("\"{0}\"", arrayValue); else sb.AppendFormat("{0}", arrayValue); } sb.Append("]"); } else { sb.AppendFormat("{0}:{1}", name, value); } } sb.Append("}"); } public override bool TryGetMember(GetMemberBinder binder, out object result) { if (!_dictionary.TryGetValue(binder.Name, out result)) { // return null to avoid exception. caller can check for null this way... result = null; return true; } result = WrapResultObject(result); return true; } public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result) { if (indexes.Length == 1 && indexes[0] != null) { if (!_dictionary.TryGetValue(indexes[0].ToString(), out result)) { // return null to avoid exception. caller can check for null this way... result = null; return true; } result = WrapResultObject(result); return true; } return base.TryGetIndex(binder, indexes, out result); } private static object WrapResultObject(object result) { var dictionary = result as IDictionary; if (dictionary != null) return new DynamicJsonObject(dictionary); var arrayList = result as ArrayList; if (arrayList != null && arrayList.Count > 0) { return arrayList[0] is IDictionary ? new List(arrayList.Cast>().Select(x => new DynamicJsonObject(x))) : new List(arrayList.Cast()); } return result; } } #endregion } 

Puedes usarlo así:

 string json = ...; var serializer = new JavaScriptSerializer(); serializer.RegisterConverters(new[] { new DynamicJsonConverter() }); dynamic obj = serializer.Deserialize(json, typeof(object)); 

Entonces, dada una cadena JSON:

 { "Items":[ { "Name":"Apple", "Price":12.3 }, { "Name":"Grape", "Price":3.21 } ], "Date":"21/11/2010" } 

El siguiente código funcionará en tiempo de ejecución:

 dynamic data = serializer.Deserialize(json, typeof(object)); data.Date; // "21/11/2010" data.Items.Count; // 2 data.Items[0].Name; // "Apple" data.Items[0].Price; // 12.3 (as a decimal) data.Items[1].Name; // "Grape" data.Items[1].Price; // 3.21 (as a decimal) 

Es bastante simple usar Json.NET :

 dynamic stuff = JsonConvert.DeserializeObject("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }"); string name = stuff.Name; string address = stuff.Address.City; 

También using Newtonsoft.Json.Linq :

 dynamic stuff = JObject.Parse("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }"); string name = stuff.Name; string address = stuff.Address.City; 

Documentación: consultar JSON con dinámica

Puede hacer esto usando System.Web.Helpers.Json : su método Decode devuelve un objeto dynamic que puede recorrer a su gusto.

Está incluido en el ensamblado System.Web.Helpers (.NET 4.0).

 var dynamicObject = Json.Decode(jsonString); 

.Net 4.0 tiene una biblioteca incorporada para hacer esto:

 using System.Web.Script.Serialization; JavaScriptSerializer jss = new JavaScriptSerializer(); var d=jss.Deserialize(str); 

Esta es la forma más simple.

Simple “cadena de datos json” para oponerse sin dll de terceros

 WebClient client = new WebClient(); string getString = client.DownloadString("https://graph.facebook.com/zuck"); JavaScriptSerializer serializer = new JavaScriptSerializer(); dynamic item = serializer.Deserialize(getString); string name = item["name"]; //note: JavaScriptSerializer in this namespaces //System.Web.Script.Serialization.JavaScriptSerializer 

Nota: También puede usar su objeto personalizado.

 Personel item = serializer.Deserialize(getString); 

JsonFx puede deserializar json en objetos dynamics.

https://github.com/jsonfx/jsonfx

Serializar a / desde tipos dynamics (por defecto para .NET 4.0):

 var reader = new JsonReader(); var writer = new JsonWriter(); string input = @"{ ""foo"": true, ""array"": [ 42, false, ""Hello!"", null ] }"; dynamic output = reader.Read(input); Console.WriteLine(output.array[0]); // 42 string json = writer.Write(output); Console.WriteLine(json); // {"foo":true,"array":[42,false,"Hello!",null]} 

Hice una nueva versión del DynamicJsonConverter que usa Expando Objects. Utilicé objetos de expansión porque quería serializar la dinámica en json usando Json.net.

 using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Dynamic; using System.Web.Script.Serialization; public static class DynamicJson { public static dynamic Parse(string json) { JavaScriptSerializer jss = new JavaScriptSerializer(); jss.RegisterConverters(new JavaScriptConverter[] { new DynamicJsonConverter() }); dynamic glossaryEntry = jss.Deserialize(json, typeof(object)) as dynamic; return glossaryEntry; } class DynamicJsonConverter : JavaScriptConverter { public override object Deserialize(IDictionary dictionary, Type type, JavaScriptSerializer serializer) { if (dictionary == null) throw new ArgumentNullException("dictionary"); var result = ToExpando(dictionary); return type == typeof(object) ? result : null; } private static ExpandoObject ToExpando(IDictionary dictionary) { var result = new ExpandoObject(); var dic = result as IDictionary; foreach (var item in dictionary) { var valueAsDic = item.Value as IDictionary; if (valueAsDic != null) { dic.Add(item.Key, ToExpando(valueAsDic)); continue; } var arrayList = item.Value as ArrayList; if (arrayList != null && arrayList.Count > 0) { dic.Add(item.Key, ToExpando(arrayList)); continue; } dic.Add(item.Key, item.Value); } return result; } private static ArrayList ToExpando(ArrayList obj) { ArrayList result = new ArrayList(); foreach (var item in obj) { var valueAsDic = item as IDictionary; if (valueAsDic != null) { result.Add(ToExpando(valueAsDic)); continue; } var arrayList = item as ArrayList; if (arrayList != null && arrayList.Count > 0) { result.Add(ToExpando(arrayList)); continue; } result.Add(item); } return result; } public override IDictionary Serialize(object obj, JavaScriptSerializer serializer) { throw new NotImplementedException(); } public override IEnumerable SupportedTypes { get { return new ReadOnlyCollection(new List(new[] { typeof(object) })); } } } } 

Otra forma de usar Newtonsoft.Json :

 dynamic stuff = Newtonsoft.Json.JsonConvert.DeserializeObject("{ color: 'red', value: 5 }"); string color = stuff.color; int value = stuff.value; 

La forma más simple es

Solo incluye este dll

usa el código como este

 dynamic json = new JDynamic("{a:'abc'}"); //json.a is a string "abc" dynamic json = new JDynamic("{a:3.1416}"); //json.a is 3.1416m dynamic json = new JDynamic("{a:1}"); //json.a is dynamic json = new JDynamic("[1,2,3]"); /json.Length/json.Count is 3 //And you can use json[0]/ json[2] to get the elements dynamic json = new JDynamic("{a:[1,2,3]}"); //json.a.Length /json.a.Count is 3. //And you can use json.a[0]/ json.a[2] to get the elements dynamic json = new JDynamic("[{b:1},{c:1}]"); //json.Length/json.Count is 2. //And you can use the json[0].b/json[1].c to get the num. 

Puede extender el JavaScriptSerializer para copiar recursivamente el diccionario que creó para expandir los objetos y luego usarlos dinámicamente:

 static class JavaScriptSerializerExtensions { public static dynamic DeserializeDynamic(this JavaScriptSerializer serializer, string value) { var dictionary = serializer.Deserialize>(value); return GetExpando(dictionary); } private static ExpandoObject GetExpando(IDictionary dictionary) { var expando = (IDictionary)new ExpandoObject(); foreach (var item in dictionary) { var innerDictionary = item.Value as IDictionary; if (innerDictionary != null) { expando.Add(item.Key, GetExpando(innerDictionary)); } else { expando.Add(item.Key, item.Value); } } return (ExpandoObject)expando; } } 

Entonces solo necesita tener una statement de uso para el espacio de nombres en el que definió la extensión (considere solo definirlos en System.Web.Script.Serialization … otro truco es no usar un espacio de nombres, entonces no necesita el uso de statement en absoluto) y puedes consumirlos así:

 var serializer = new JavaScriptSerializer(); var value = serializer.DeserializeDynamic("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }"); var name = (string)value.Name; // Jon Smith var age = (int)value.Age; // 42 var address = value.Address; var city = (string)address.City; // New York var state = (string)address.State; // NY 

Para eso usaría JSON.NET para hacer el análisis de bajo nivel de la secuencia JSON y luego construir la jerarquía de objetos a partir de las instancias de la clase ExpandoObject .

Estoy usando así en mi código y está funcionando bien

 using System.Web.Script.Serialization; JavaScriptSerializer oJS = new JavaScriptSerializer(); RootObject oRootObject = new RootObject(); oRootObject = oJS.Deserialize(Your JSon String); 

Yo uso: http://json2csharp.com/ para obtener una clase que represente el objeto Json.

Entrada:

 { "name":"John", "age":31, "city":"New York", "Childs":[ { "name":"Jim", "age":11 }, { "name":"Tim", "age":9 } ] } 

Salida:

 public class Child { public string name { get; set; } public int age { get; set; } } public class Person { public string name { get; set; } public int age { get; set; } public string city { get; set; } public List Childs { get; set; } } 

Después de eso uso Newtonsoft.Json para completar la clase:

 using Newtonsoft.Json; namespace GitRepositoryCreator.Common { class JObjects { public static string Get(object p_object) { return JsonConvert.SerializeObject(p_object); } internal static T Get(string p_object) { return JsonConvert.DeserializeObject(p_object); } } } 

Puedes llamarlo así:

 Person jsonClass = JObjects.Get(stringJson); string stringJson = JObjects.Get(jsonClass); 

PD:

Si su nombre de la variable json no es un nombre válido de C # (el nombre comienza con $ ), puede corregirlo así:

 public class Exception { [JsonProperty(PropertyName = "$id")] public string id { get; set; } public object innerException { get; set; } public string message { get; set; } public string typeName { get; set; } public string typeKey { get; set; } public int errorCode { get; set; } public int eventId { get; set; } } 

Puede usar el using Newtonsoft.Json

 var jRoot = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(resolvedEvent.Event.Data)); 

resolvedEvent.Event.Data es mi respuesta al llamar al evento central.

Es probable que sea un poco tarde para ayudarlo, pero el objeto que desea DynamicJSONObject está incluido en System.Web.Helpers.dll del paquete ASP.NET Web Pages, que es parte de WebMatrix.

Hay una biblioteca JSON ligera para C # llamada SimpleJson que se puede encontrar en http://simplejson.codeplex.com https://github.com/facebook-csharp-sdk/simple-json

Es compatible con .net 3.5+, Silverlight y Windows Phone 7.

Admite dinámica para .net 4.0

También se puede instalar como un paquete nuget

 Install-Package SimpleJson 

use DataSet (C #) Con la función javascript simple para crear una secuencia json con la entrada DataSet create json like (multi table dataset) [[{a: 1, b: 2, c: 3}, {a: 3, b: 5, c : 6}], [{a: 23, b: 45, c: 35}, {a: 58, b: 59, c: 45}]]

solo cliente uso lateral eval por ejemplo

var d = eval (‘[[{a: 1, b: 2, c: 3}, {a: 3, b: 5, c: 6}], [{a: 23, b: 45, c: 35 }, {a: 58, b: 59, c: 45}]] ‘)

luego usa

d [0] [0] .a // fuera 1 de la tabla 0 fila 0

d [1] [1] .b // fuera 59 de la tabla 1 fila 1

 //create by Behnam Mohammadi And Saeed Ahmadian public string jsonMini(DataSet ds) { int t=0, r=0, c=0; string stream = "["; for (t = 0; t < ds.Tables.Count; t++) { stream += "["; for (r = 0; r < ds.Tables[t].Rows.Count; r++) { stream += "{"; for (c = 0; c < ds.Tables[t].Columns.Count; c++) { stream += ds.Tables[t].Columns[c].ToString() + ":'" + ds.Tables[t].Rows[r][c].ToString() + "',"; } if(c>0) stream = stream.Substring(0, stream.Length - 1); stream += "},"; } if(r>0) stream = stream.Substring(0, stream.Length - 1); stream += "],"; } if(t>0) stream = stream.Substring(0, stream.Length - 1); stream += "];"; return stream; } 

La deserialización en JSON.NET puede ser dinámica utilizando la clase JObject , que se incluye en esa biblioteca. Mi cadena JSON representa estas clases:

 public class Foo { public int Age {get;set;} public Bar Bar {get;set;} } public class Bar { public DateTime BDay {get;set;} } 

Ahora deserializamos la cadena SIN hacer referencia a las clases anteriores:

 var dyn = JsonConvert.DeserializeObject(jsonAsFooString); JProperty propAge = dyn.Properties().FirstOrDefault(i=>i.Name == "Age"); if(propAge != null) { int age = int.Parse(propAge.Value.ToString()); Console.WriteLine("age=" + age); } //or as a one-liner: int myage = int.Parse(dyn.Properties().First(i=>i.Name == "Age").Value.ToString()); 

O si quieres profundizar:

 var propBar = dyn.Properties().FirstOrDefault(i=>i.Name == "Bar"); if(propBar != null) { JObject o = (JObject)propBar.First(); var propBDay = o.Properties().FirstOrDefault (i => i.Name=="BDay"); if(propBDay != null) { DateTime bday = DateTime.Parse(propBDay.Value.ToString()); Console.WriteLine("birthday=" + bday.ToString("MM/dd/yyyy")); } } //or as a one-liner: DateTime mybday = DateTime.Parse(((JObject)dyn.Properties().First(i=>i.Name == "Bar").First()).Properties().First(i=>i.Name == "BDay").Value.ToString()); 

Ver la publicación para un ejemplo completo.

Mira el artículo que escribí en CodeProject, uno que responde la pregunta con precisión:

Tipos dynamics con JSON.NET

Hay demasiado para volver a publicarlo todo aquí, e incluso menos puntos ya que ese artículo tiene un archivo adjunto con la clave / archivo fuente requerido.

Para obtener un ExpandoObject:

 using Newtonsoft.Json; using Newtonsoft.Json.Converters; Container container = JsonConvert.Deserialize(jsonAsString, new ExpandoObjectConverter()); 

prueba esto –

  var units = new { Name = "Phone", Color= "White" }; var jsonResponse = JsonConvert.DeserializeAnonymousType(json, units ); 

Otra opción es “Pegar JSON como clases” para que pueda ser deserializado de forma rápida y fácil.

  1. Simplemente copie todo su JSON
  2. En VS: haga clic en Edición> Pegado especial> Pegar JSON como clases

Aquí hay una mejor explicación en piccas … https://blogs.msdn.microsoft.com/webdev/2012/12/18/paste-json-as-classes-in-asp-net-and-web-tools- 2012-2-rc /

Cómo analizar easy json con dynamic & JavaScriptSerializer

Agregue referencia de System.Web.Extensions y agregue este espacio de nombres using System.Web.Script.Serialization; hasta arriba

 public static void EasyJson() { var jsonText = @"{ ""some_number"": 108.541, ""date_time"": ""2011-04-13T15:34:09Z"", ""serial_number"": ""SN1234"" }"; var jss = new JavaScriptSerializer(); var dict = jss.Deserialize(jsonText); Console.WriteLine(dict["some_number"]); Console.ReadLine(); } 

Cómo analizar el json nested y complejo con dynamic & JavaScriptSerializer

Agregue referencia de System.Web.Extensions y agregue este espacio de nombres using System.Web.Script.Serialization; hasta arriba

 public static void ComplexJson() { var jsonText = @"{ ""some_number"": 108.541, ""date_time"": ""2011-04-13T15:34:09Z"", ""serial_number"": ""SN1234"", ""more_data"": { ""field1"": 1.0, ""field2"": ""hello"" } }"; var jss = new JavaScriptSerializer(); var dict = jss.Deserialize(jsonText); Console.WriteLine(dict["some_number"]); Console.WriteLine(dict["more_data"]["field2"]); Console.ReadLine(); }