¿Deserializar JSON en objeto dinámico C #?

966

¿Hay alguna manera de deserializar el contenido JSON en un tipo dinámico C # 4? Sería bueno omitir la creación de un montón de clases para usar el DataContractJsonSerializer.

jswanson
fuente
55
Si quieres algo 'dinámico', ¿por qué no usar los accesos get-style que vienen con la mayoría de los decodificadores JSON que no van a objetos simples y antiguos? (por ejemplo, ¿existe realmente la necesidad de crear objetos 'dinámicos'?) json.org tiene un montón de enlaces para implementaciones de C # JSON.
Estoy trabajando en un proyecto que intenta mantener las dependencias externas al mínimo. Entonces, si es posible hacer algo con los serializadores .net y los tipos de acciones que serían preferidos. Por supuesto, si no es posible, estoy llamando a json.org. ¡Gracias!
jswanson
42
Estoy realmente sorprendido de que el equipo de C # haya agregado "dinámico", pero luego no hay forma en el CLR de convertir un objeto JSON en una instancia de clase CLR dinámica.
Frank Schwieterman
2
Lamentablemente, la respuesta aceptada no funciona en .NET 4 RTM. Publiqué una respuesta que me ayudó a ponerme en marcha, lo que podría ser útil para otros.
Drew Noakes
(Aunque parece que Newtonsoft JSON.NET se acerca bastante. Sin embargo, no hay ejemplos realmente buenos).
Hot Licks

Respuestas:

660

Si está contento de tener una dependencia en el System.Web.Helpersensamblado, puede usar la Jsonclase:

dynamic data = Json.Decode(json);

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


Aquí se sugiere un enfoque alternativo de deserialización . Modifiqué un poco el código para corregir un error y adaptarme a mi estilo de codificación. Todo lo que necesita es este código y una referencia System.Web.Extensionsde 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<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        if (dictionary == null)
            throw new ArgumentNullException("dictionary");

        return type == typeof(object) ? new DynamicJsonObject(dictionary) : null;
    }

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override IEnumerable<Type> SupportedTypes
    {
        get { return new ReadOnlyCollection<Type>(new List<Type>(new[] { typeof(object) })); }
    }

    #region Nested type: DynamicJsonObject

    private sealed class DynamicJsonObject : DynamicObject
    {
        private readonly IDictionary<string, object> _dictionary;

        public DynamicJsonObject(IDictionary<string, object> 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<string, object>)
                {
                    new DynamicJsonObject((IDictionary<string, object>)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<string, object>)
                            new DynamicJsonObject((IDictionary<string, object>)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<string, object>;
            if (dictionary != null)
                return new DynamicJsonObject(dictionary);

            var arrayList = result as ArrayList;
            if (arrayList != null && arrayList.Count > 0)
            {
                return arrayList[0] is IDictionary<string, object> 
                    ? new List<object>(arrayList.Cast<IDictionary<string, object>>().Select(x => new DynamicJsonObject(x))) 
                    : new List<object>(arrayList.Cast<object>());
            }

            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)
Drew Noakes
fuente
1
Me sale un error en obj dinámico = serializador. Deserializar (json, typeof (objeto)); diciendo que no hay sobrecarga para el método con 2 argumentos ... dll incorrecto o qué?
Stewie Griffin
32
Puede usar System.Web.Helpers.Json: ofrece un método de decodificación que devuelve un objeto dinámico. También publiqué esta información como respuesta.
Vlad Iliescu
2
Esto también me ayudó mucho, pero tengo curiosidad por saber qué debo hacer si necesito usar el método .Serialize, que actualmente solo arroja una excepción NotImplementedException ... No estoy demasiado familiarizado con las clases selladas y / o el resumen extendido clases ¿Alguien puede señalarme en la dirección correcta?
Cory
2
a veces en js tienes campos con caracteres especiales como "color de fondo". Para acceder a dichos campos en js debe hacer obj ["color de fondo"]. ¿Cómo puedo acceder a dichos campos desde c # después de deserializar a objeto dinámico? No puedo hacer obj.background-color, por supuesto, y obj ["background-color"] no parece funcionar. Sería bueno si también se pudiera acceder al objeto dinámico como un diccionario, al mismo tiempo, exactamente como en js.
Radu Simionescu
2
@RaduSimionescu Probablemente llego un poco tarde, pero tal vez esto ayude a los futuros visitantes. Tuve el mismo problema, solo con el nombre del campo params(que es una palabra clave en C #). Además TryGetMember, puede anular TryGetIndex, lo que le proporciona exactamente el mismo comportamiento que en JS. Entonces puede hacer obj["params"]o obj["background-color"]para nombres de campo incómodos.
Martin Ender
606

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

Tom Peplow
fuente
99
@HotLicks: para introspectar la dinámica, stuffhaga algo como:foreach (Newtonsoft.Json.Linq.JProperty jproperty in stuff) { Console.WriteLine("jproperty.Name = {0}", jproperty.Name);}
Matthias
11
¿Cuál es la diferencia entre JsonConvert.DeserializeObject y JObject.Parse? La respuesta es usarlos a ambos de la misma manera para hacer lo mismo, pero no explica la diferencia.
cja
77
@TomPeplow Probé esto. No me funcionó. Dice que "JObject no implementa 'Nombre'".
Lee Louviere
44
@cja no hay diferencia: stackoverflow.com/questions/23645034/…
nawfal
8
No puedo hacer que esto funcione. He reducido el problema a estar dentro de un asyncmétodo. Si hago el método sincrónico, funciona como se esperaba. Sin embargo, crea el método asyncy no puedo obtener un dynamic, solo obtengo un object. El casting explícito no hace nada, solo me da un object. ¿Hay alguien más experimentando esto?
codeConcussion
295

Puede hacerlo utilizando System.Web.Helpers.Json : su método Decode devuelve un objeto dinámico que puede atravesar a su gusto.

Se incluye en el ensamblado System.Web.Helpers (.NET 4.0).

var dynamicObject = Json.Decode(jsonString);
Vlad Iliescu
fuente
25
FYI System.Web.Helpers.dll requiere .net 4.0 pero no está incluido en .net 4.0. Se puede instalar con ASP.NET MVC 3
jbtule
77
Encontrará este ensamblado en el grupo Extensiones en Ensamblajes en Visual Studio 2012
W3Max
1
¿Algún problema con el uso dinámico? ¿Cómo podemos manejar las excepciones de manera eficiente si la entrada JSON no contiene las propiedades ..
Usama Khalil
55
Si desea escribir fuertemente el modelo, asegúrese de utilizar el método Json.Decode <T> (string).
Mike
2
Para agregar esta biblioteca a su proyecto: stackoverflow.com/questions/8037895/…
80

.NET 4.0 tiene una biblioteca incorporada para hacer esto:

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

Esta es la forma más simple.

Peter Long
fuente
27
has intentado esto? Vuelve Dictionary<string,object>. A menos que me falte algo, su ejemplo no devuelve un objeto dinámico.
sergiopereira
18
Esto no funciona, solo devuelve un dict en forma de dinámica
mattmanser
55
@ Peter Long Creo que no he podido exponer mi caso claramente, querido amigo. Permítame intentar rectificar mi error. Sé lo que es una dinámica. Esto no le permite pasar un objeto JSON y usar d.code, tendría que hacer d ["código"]. Valor, que no es lo que la mayoría de las personas que encuentran esta respuesta quieren, ya sabemos cómo obtener el diccionario y convertirlo en dinámico es una pérdida total de tiempo. Respetuosamente no estoy de acuerdo, señor.
mattmanser 01 de
44
@mattmanser, we already know how to get the dictionary and casting it to a dynamic. No tiene que ser un dictionay. Json también tiene listas además del diccionario. Y también se pueden anidar listas y diccionarios. Mi código podría manejar todas estas situaciones. PERO su método NO puede.
Peter Long
44
@mattmanser tiene razón; es posible implementar IDynamicMetaObjectProvider(o usar, por ejemplo ExpandoObject) que pueda interceptar propiedades y buscarlas en un diccionario interno. Esto combinado con el uso de dynamicpermite código como d.codepara ser utilizado. No tiene sentido lanzar un diccionario a una dinámica.
Stephen Drew el
78

"Datos JSON de cadena" simples para objetar sin ningún archivo DLL de terceros:

WebClient client = new WebClient();
string getString = client.DownloadString("https://graph.facebook.com/zuck");

JavaScriptSerializer serializer = new JavaScriptSerializer();
dynamic item = serializer.Deserialize<object>(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<Personel>(getString);
İbrahim Özbölük
fuente
44
No lo entiendo. Esta es, con mucho, la solución más simple y nadie lo menciona.
cikatomo
2
sí, es simple :) en algún momento necesitas serializar pero no quieres incluir la tercera parte dll
İbrahim Özbölük
¿Puede dar más detalles sobre: ​​qué tan dinámico puede acceder al objeto serializado a través de myObject["myprop"]:? Sé que se realiza en tiempo de ejecución, pero ¿cómo myObject["myprop"]es válido acceder a través de él ?
Royi Namir
1
Puedes deserializar tu objeto como Personel item = serializer.Deserialize <Personel> (getString); y si usas un objeto dinámico también puedes usar una matriz y todo es posible como todo objeto
İbrahim Özbölük
3
Para usar el espacio de nombres System.Web.Script.Serialization, su proyecto necesita una referencia a System.Web.Extensions.
StilgarISCA
28

JsonFx puede deserializar el contenido JSON en objetos dinámicos.

Serializar hacia / desde tipos dinámicos (predeterminado 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]}
jbtule
fuente
19

Hice una nueva versión del DynamicJsonConverter que usa objetos Expando. Utilicé objetos expando, porque quería serializar la dinámica nuevamente 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<string, object> 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<string, object> dictionary)
        {
            var result = new ExpandoObject();
            var dic = result as IDictionary<String, object>;

            foreach (var item in dictionary)
            {
                var valueAsDic = item.Value as IDictionary<string, object>;
                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<string, object>;
                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<string, object> Serialize(object obj, JavaScriptSerializer serializer)
        {
            throw new NotImplementedException();
        }

        public override IEnumerable<Type> SupportedTypes
        {
            get { return new ReadOnlyCollection<Type>(new List<Type>(new[] { typeof(object) })); }
        }
    }
}
Jason Bolton
fuente
18

Otra forma de usar Newtonsoft.Json :

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

Puede lograr eso con la ayuda de Newtonsoft.Json. Instale Newtonsoft.Json desde Nuget y el:

using Newtonsoft.Json;

dynamic results = JsonConvert.DeserializeObject<dynamic>(YOUR_JSON);
Waleed Naveed
fuente
8

La forma más simple es:

Simplemente incluya este archivo DLL .

Use 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.
usuario1006544
fuente
6

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<IDictionary<string, object>>(value);
        return GetExpando(dictionary);
    }

    private static ExpandoObject GetExpando(IDictionary<string, object> dictionary)
    {
        var expando = (IDictionary<string, object>)new ExpandoObject();

        foreach (var item in dictionary)
        {
            var innerDictionary = item.Value as IDictionary<string, object>;
            if (innerDictionary != null)
            {
                expando.Add(item.Key, GetExpando(innerDictionary));
            }
            else
            {
                expando.Add(item.Key, item.Value);
            }
        }

        return (ExpandoObject)expando;
    }
}

Entonces solo necesita tener una declaración de uso para el espacio de nombres en el que definió la extensión (considere simplemente definirlos en System.Web.Script.Serialization ... otro truco es no usar un espacio de nombres, entonces no necesita el uso declaración en absoluto) y puede 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
alonzofox
fuente
6

Puedes usar using Newtonsoft.Json

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

resolvedEvent.Event.Data es mi respuesta al llamar a Core Event.

Vivek Shukla
fuente
6

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<Child> Childs { get; set; }
}

Después de eso uso Newtonsoft.Json para llenar 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<T>(string p_object)
        {
            return JsonConvert.DeserializeObject<T>(p_object);
        }
    }
}

Puedes llamarlo así:

Person jsonClass = JObjects.Get<Person>(stringJson);

string stringJson = JObjects.Get(jsonClass);

PD:

Si su nombre de variable JSON no es un nombre válido de C # (el nombre comienza con $), puede solucionarlo de esta manera:

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; }
}
RoJaIt
fuente
5

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 instancias de la ExpandoObjectclase.

Daniel Earwicker
fuente
5

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<RootObject>(Your JSon String);
Vasim Shaikh
fuente
1
pero esa no es la pregunta que se hace. Hay una diferencia cuando tienes que especificar el tipo para cada cadena json y trabajar con el tipo dinámico.
Illuminati
5

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

Tipos dinámicos con JSON.NET

Hay demasiado para volver a publicarlo todo aquí, y menos aún porque ese artículo tiene un archivo adjunto con la clave / archivo fuente requerido.

vitaly-t
fuente
5

Otra opción es "Pegar JSON como clases" para que se pueda deserializar de forma rápida y fácil.

  1. Simplemente copie su JSON completo
  2. En Visual Studio: haga clic en EditarPegado especialPegar JSON como clases

Aquí hay una mejor explicación n piccas ... 'Pegar JSON como clases' en ASP.NET y Web Tools 2012.2 RC

nitsram
fuente
¡Esto me ahorró mucho tiempo! debe elegirse como mejor respuesta!
jsiot
4

La deserialización en JSON.NET puede ser dinámica utilizando la JObjectclase, 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<JObject>(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 publicación para un ejemplo completo.

Chad Kuehn
fuente
Este enfoque permite "atravesar" el documento jSON, de modo que pueda administrar la situación en la que la estructura JSON es desconocida o variable (por ejemplo, muchas API devuelven un documento JSON completamente diferente cuando se produce un error). ¿Hay otras bibliotecas que permiten hacer eso, aparte de Newtonsoft.JSON (también conocido como JSON.NET)?
Alex 75
4

El objeto que desea DynamicJSONObject se incluye en System.Web.Helpers.dll del paquete de páginas web ASP.NET, que forma parte de WebMatrix.

Nick Daniels
fuente
4

Hay una biblioteca JSON liviana para C # llamada SimpleJson .

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
prabir
fuente
4

Use DataSet (C #) con JavaScript. Una función simple para crear una secuencia JSON con entrada de DataSet. Cree contenido JSON como (conjunto de datos de varias tablas):

[[{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 del lado del cliente, use 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 use:

d[0][0].a // out 1 from table 0 row 0

d[1][1].b // out 59 from table 1 row 1

// Created 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;
}
Behnam Mohammadi
fuente
3

Para obtener un Objeto de Expando:

using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

Container container = JsonConvert.Deserialize<Container>(jsonAsString, new ExpandoObjectConverter());
Ryan Norbauer
fuente
3

Prueba esto:

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

Cómo analizar contenido JSON fácil con Dynamic & JavaScriptSerializer

Agregue la referencia de System.Web.Extensions y agregue este espacio using System.Web.Script.Serialization;de nombres en la parte superior:

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<dynamic>(jsonText);

    Console.WriteLine(dict["some_number"]);
    Console.ReadLine();
}

Cómo analizar JSON anidado y complejo con Dynamic y JavaScriptSerializer

Agregue la referencia de System.Web.Extensions y agregue este espacio using System.Web.Script.Serialization;de nombres en la parte superior:

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<dynamic>(jsonText);

    Console.WriteLine(dict["some_number"]);
    Console.WriteLine(dict["more_data"]["field2"]);
    Console.ReadLine();
}
Niebla
fuente
1

Con Cinchoo ETL , una biblioteca de código abierto disponible para analizar JSON en un objeto dinámico:

string json = @"{
    ""key1"": [
        {
            ""action"": ""open"",
            ""timestamp"": ""2018-09-05 20:46:00"",
            ""url"": null,
            ""ip"": ""66.102.6.98""
        }
    ]
}";
using (var p = ChoJSONReader.LoadText(json)
    .WithJSONPath("$.*")
    )
{
    foreach (var rec in p)
    {
        Console.WriteLine("Action: " + rec.action);
        Console.WriteLine("Timestamp: " + rec.timestamp);
        Console.WriteLine("URL: " + rec.url);
        Console.WriteLine("IP address: " + rec.ip);
    }
}

Salida:

Action: open
Timestamp: 2018-09-05 20:46:00
URL: http://www.google.com
IP address: 66.102.6.98

Descargo de responsabilidad: soy el autor de esta biblioteca.

RajN
fuente
0

intenta de esta manera!

Ejemplo de JSON:

  [{
            "id": 140,
            "group": 1,
            "text": "xxx",
            "creation_date": 123456,
            "created_by": "[email protected]",
            "tags": ["xxxxx"]
        }, {
            "id": 141,
            "group": 1,
            "text": "xxxx",
            "creation_date": 123456,
            "created_by": "[email protected]",
            "tags": ["xxxxx"]
        }]

Código C #:

        var jsonString = (File.ReadAllText(Path.Combine(Directory.GetCurrentDirectory(),"delete_result.json")));
        var objects = JsonConvert.DeserializeObject<dynamic>(jsonString);
        foreach(var o in objects)
        {
            Console.WriteLine($"{o.id.ToString()}");
        }
Acero azul
fuente