Desserializar JSON em objeto dinâmico C #?

965

Existe uma maneira de desserializar o conteúdo JSON em um tipo dinâmico C # 4? Seria bom pular a criação de um monte de classes para usar o DataContractJsonSerializer.

jswanson
fonte
5
Se você deseja algo 'dinâmico', por que não usar apenas os acessadores de estilo get que acompanham a maioria dos decodificadores JSON que não vão para objetos antigos simples? (por exemplo, existe realmente a necessidade de criação de objetos 'dinâmicos'?) O json.org possui vários links para implementações em C # JSON.
Estou trabalhando em um projeto que está tentando manter as dependências externas no mínimo. Portanto, se é possível encontrar algo com os serializadores .net e os tipos preferidos. Claro que, se não for possível, estou acessando o json.org. Obrigado!
jswanson
42
Estou realmente surpreso que a equipe de C # tenha adicionado 'dinâmico', mas não há como, no CLR, converter um objeto JSON em uma instância de classe dinâmica do CLR.
24510 Frank Schwieterman
2
Infelizmente, a resposta aceita não funciona no .NET 4 RTM. Publiquei uma resposta que me ajudou a seguir adiante, o que pode ser útil para outras pessoas.
Drew Noakes
(Embora pareça que Newtonsoft JSON.NET chega bem perto Não há qualquer realmente bons exemplos, no entanto..)
Hot Licks

Respostas:

659

Se você estiver feliz por ter uma dependência da System.Web.Helpersmontagem, poderá usar a Jsonclasse:

dynamic data = Json.Decode(json);

Ele está incluído na estrutura MVC como um download adicional para a estrutura .NET 4. Certifique-se de dar um voto positivo a Vlad, se isso for útil! No entanto, se você não puder assumir que o ambiente do cliente inclui esta DLL, continue a ler.


Uma abordagem alternativa de desserialização é sugerida aqui . Modifiquei o código levemente para corrigir um erro e se adequar ao meu estilo de codificação. Tudo o que você precisa é deste código e uma referência System.Web.Extensionsdo seu projeto:

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
}

Você pode usá-lo assim:

string json = ...;

var serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new[] { new DynamicJsonConverter() });

dynamic obj = serializer.Deserialize(json, typeof(object));

Portanto, dada uma string JSON:

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

O código a seguir funcionará em tempo de execução:

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
fonte
1
Eu recebo um erro no dinâmico obj = serializer.Deserialize (json, typeof (object)); dizendo que não há sobrecarga para o método com 2 argumentos..dll errado ou o quê?
Stewie Griffin
32
Você pode usar System.Web.Helpers.Json - ele oferece um método Decode que retorna um objeto dinâmico. Também publiquei essas informações como resposta.
Vlad Iliescu 29/02
2
Isso também me ajudou muito, mas estou curioso para saber o que devo fazer se precisar usar o método .Serialize, que atualmente gera apenas uma NotImplementedException ... Não estou familiarizado com classes seladas e / ou resumo estendido Aulas. Alguém pode me apontar na direção certa?
Cory W.
2
às vezes em js você tem campos com caracteres especiais como "background-color". Para acessar esses campos em js, você obj ["background-color"]. Como posso acessar esses campos de c # após desserializar para objeto dinâmico? Não posso fazer obj.background-color, é claro, e obj ["background-color"] parece não funcionar. Seria bom se o objeto dinâmico também pudesse ser acessado como um dicionário, ao mesmo tempo, exatamente como em js.
Radu Simionescu 28/09/12
2
@RaduSimionescu Provavelmente estou um pouco atrasado, mas talvez isso ajude futuros visitantes. Eu tive o mesmo problema, apenas com o nome do campo params(que é uma palavra-chave em c #). Além de TryGetMembervocê pode substituir TryGetIndex, o que fornece exatamente o mesmo comportamento que em JS. Então você pode fazer obj["params"]ou obj["background-color"]para nomes de campos estranhos.
Martin Ender
606

É bem simples usando o 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;

Também 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;

Documentation: Consultando JSON com Dynamic

Tom Peplow
fonte
9
@HotLicks: para a introspecção a dinâmica stufffazer algo como:foreach (Newtonsoft.Json.Linq.JProperty jproperty in stuff) { Console.WriteLine("jproperty.Name = {0}", jproperty.Name);}
Matthias
11
Qual é a diferença entre JsonConvert.DeserializeObject e JObject.Parse? A resposta é usá-los da mesma maneira para fazer a mesma coisa, mas não explica a diferença.
CJA
7
@TomPeplow Tentei isso. Não funcionou para mim. Ele diz que "JObject não implementa 'Nome'".
Lee Louviere
4
@ cja nenhuma diferença: stackoverflow.com/questions/23645034/…
nawfal
8
Não consigo fazer isso funcionar. Eu reduzi o problema para dentro de um asyncmétodo. Se eu tornar o método síncrono, ele funcionará conforme o esperado. No entanto, faça o método asynce não consigo obter um dynamic, apenas recebo um object. A transmissão explícita não faz nada, ainda me dá uma object. Alguém mais está experimentando isso?
codeConcussion
295

Você pode fazer isso usando System.Web.Helpers.Json - seu método Decode retorna um objeto dinâmico que você pode atravessar como quiser.

Está incluído no assembly System.Web.Helpers (.NET 4.0).

var dynamicObject = Json.Decode(jsonString);
Vlad Iliescu
fonte
25
Para sua informação, o System.Web.Helpers.dll requer .net 4.0, mas não está incluído no .net 4.0. Ele pode ser instalado com o ASP.NET MVC 3
jbtule
7
Você encontrará esse assembly no grupo Extensões em Assemblies no Visual Studio 2012
W3Max 17/13
1
Algum problema com o uso dinâmico? Como podemos lidar com exceções de forma eficiente se a entrada JSON não contém as propriedades ..
Osama Khalil
5
Se você deseja digitar fortemente o modelo, use o método Json.Decode <T> (string).
15553 Mike
2
Para adicionar esta biblioteca ao seu projeto: stackoverflow.com/questions/8037895/…
80

O .NET 4.0 possui uma biblioteca interna para fazer isso:

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

Esta é a maneira mais simples.

Peter Long
fonte
27
você já tentou isso? Retorna Dictionary<string,object>. A menos que esteja faltando alguma coisa, seu exemplo não retorna um objeto dinâmico.
sergiopereira 13/06
18
Isso não funciona, ele só retornar um dicionário na forma de uma dinâmica
mattmanser
55
@ Peter Long Eu acredito que falhei em declarar meu caso claramente, querido companheiro. Deixe-me tentar corrigir meu erro. Eu sei o que é uma dinâmica. Isso não permite que você passe um objeto JSON e use d.code, você teria que fazer d ["code"]. Value, que não é o que a maioria das pessoas que encontra essa resposta deseja, já sabemos como obter o dicionário e convertê-lo para uma dinâmica é uma total perda de tempo. Eu discordo respeitosamente, senhor.
mattmanser
4
@mattmanser we already know how to get the dictionary and casting it to a dynamic,. Não precisa ser um ditado. Json também tem listas além do dicionário. E também listas e dicionários podem ser aninhados. Meu código pode lidar com todas essas situações. MAS o seu método NÃO pode.
Peter Long
4
@mattmanser está certo; é possível implementar IDynamicMetaObjectProvider(ou usar, por exemplo ExpandoObject) capaz de interceptar propriedades e procurá-las em um dicionário interno. Isso combinado com o uso de dynamicpermite que códigos como d.codesejam usados. É meio inútil converter um dicionário em uma dinâmica.
Stephen Drew
78

Simples "string JSON data" para objetar sem nenhum arquivo DLL de terceiros:

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: Você também pode usar seu objeto personalizado.

Personel item = serializer.Deserialize<Personel>(getString);
İbrahim Özbölük
fonte
4
Eu não entendi. Essa é de longe a solução mais simples e ninguém a menciona.
cikatomo
2
Sim, é simples :) algum momento você precisa serializar mas não quer incluir 3ª dll parte
İbrahim Özbölük
Você pode elaborar sobre: ​​quão dinâmico pode acessar o objeto DEserialized via myObject["myprop"]:? Eu sei que é feito em tempo de execução, mas como o acesso myObject["myprop"]é válido?
Royi Namir 19/09/2013
1
Você pode desserializar seu objeto como item Personel = serializer.Deserialize <Personel> (getString); e se você usar objeto dinâmico também pode usar variedade e tudo é possível, como everyobject
İbrahim Özbölük
3
Para usar o espaço para nome System.Web.Script.Serialization, seu projeto precisa de uma referência a System.Web.Extensions.
perfil completo de Stilgar
28

O JsonFx pode desserializar o conteúdo JSON em objetos dinâmicos.

Serializar de / para tipos dinâmicos (padrão 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
fonte
19

Eu fiz uma nova versão do DynamicJsonConverter que usa o Expando Objects. Eu usei expando objetos, porque queria serializar a dinâmica novamente no JSON usando o 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
fonte
18

Outra maneira de usar o Newtonsoft.Json :

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

Você pode conseguir isso com a ajuda do Newtonsoft.Json. Instale o Newtonsoft.Json a partir do Nuget e o:

using Newtonsoft.Json;

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

A maneira mais simples é:

Basta incluir este arquivo DLL .

Use o 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.
user1006544
fonte
6

Você pode estender o JavaScriptSerializer para copiar recursivamente o dicionário criado para expandir o (s) objeto (s) e usá-los dinamicamente:

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

Então você só precisa ter uma instrução using para o namespace em que você definiu a extensão (considere defini-las em System.Web.Script.Serialization ... outro truque é não usar um namespace, então você não precisa usar ) e você pode consumi-los da seguinte maneira:

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
fonte
6

Você pode usar using Newtonsoft.Json

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

resolvedEvent.Event.Data é a minha resposta ao chamar o evento principal.

Vivek Shukla
fonte
6

Eu uso http://json2csharp.com/ para obter uma classe representando o objeto JSON.

Entrada:

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

Resultado:

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

Depois disso, uso o Newtonsoft.Json para preencher a classe:

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

Você pode chamar assim:

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

string stringJson = JObjects.Get(jsonClass);

PS:

Se o nome da variável JSON não for um nome C # válido (o nome começa com $), você poderá corrigir isso assim:

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
fonte
5

Para isso, eu usaria o JSON.NET para fazer a análise de baixo nível do fluxo JSON e criar a hierarquia de objetos a partir das instâncias da ExpandoObjectclasse.

Daniel Earwicker
fonte
5

Estou usando assim no meu código e está funcionando bem

using System.Web.Script.Serialization;
JavaScriptSerializer oJS = new JavaScriptSerializer();
RootObject oRootObject = new RootObject();
oRootObject = oJS.Deserialize<RootObject>(Your JSon String);
Vasim Shaikh
fonte
1
mas não é sobre isso que a pergunta está sendo feita. há um diferente quando você precisa especificar o tipo para cada string json e trabalhar com o tipo dinâmico.
Illuminati
5

Veja o artigo que escrevi no CodeProject, que responde com precisão à pergunta:

Tipos dinâmicos com JSON.NET

Há muito para republicar tudo aqui, e menos ainda, pois esse artigo tem um anexo com o arquivo de origem chave / necessário.

vitaly-t
fonte
5

Outra opção é "Colar JSON como classes" para que possa ser desserializado de maneira rápida e fácil.

  1. Basta copiar todo o JSON
  2. No Visual Studio: Clique em EditarColar EspecialColar JSON como Classes

Aqui está uma explicação melhor n piccas ... 'Colar JSON como classes' no ASP.NET e na Web Tools 2012.2 RC

nitsram
fonte
isso me salvou muito tempo! deve ser escolhido como a melhor resposta!
jsiot 17/03
4

A desserialização no JSON.NET pode ser dinâmica usando a JObjectclasse, incluída nessa biblioteca. Minha string JSON representa estas classes:

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

public class Bar {
   public DateTime BDay {get;set;}
}

Agora desserializamos a string SEM referenciar as classes acima:

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

Ou se você quiser ir mais fundo:

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

Veja a publicação para um exemplo completo.

Chad Kuehn
fonte
Essa abordagem permite "atravessar" o documento jSON, para que você possa gerenciar situações em que a estrutura JSON é desconhecida ou variável (por exemplo, muitas API retornam um documento JSON completamente diferente quando ocorre um erro). Existem outras bibliotecas que permitem isso, além do Newtonsoft.JSON (também conhecido como JSON.NET)?
Alex 75
4

O objeto que você deseja DynamicJSONObject está incluído no System.Web.Helpers.dll do pacote ASP.NET Web Pages, que faz parte do WebMatrix.

Nick Daniels
fonte
4

Existe uma biblioteca JSON leve para C # chamada SimpleJson .

Ele suporta .NET 3.5+, Silverlight e Windows Phone 7.

Ele suporta dinâmico para .NET 4.0

Também pode ser instalado como um pacote NuGet

Install-Package SimpleJson
prabir
fonte
4

Use DataSet (C #) com JavaScript. Uma função simples para criar um fluxo JSON com entrada DataSet. Crie conteúdo JSON como (conjunto de dados de várias tabelas):

[[{a:1,b:2,c:3},{a:3,b:5,c:6}],[{a:23,b:45,c:35},{a:58,b:59,c:45}]]

Apenas do lado do cliente, use eval. Por exemplo,

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}]]')

Então 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
fonte
3

Para obter um ExpandoObject:

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

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

Tente o seguinte:

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

Como analisar conteúdo JSON fácil com dinâmico e JavaScriptSerializer

Adicione a referência de System.Web.Extensions e adicione este espaço using System.Web.Script.Serialization;para nome na 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();
}

Como analisar json aninhado e complexo com dynamic & JavaScriptSerializer

Adicione a referência de System.Web.Extensions e adicione este espaço using System.Web.Script.Serialization;para nome na 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();
}
Névoa
fonte
1

Com o Cinchoo ETL - uma biblioteca de código aberto disponível para analisar o JSON em um 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);
    }
}

Resultado:

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

Disclaimer: Eu sou o autor desta biblioteca.

RajN
fonte
0

tente assim!

Exemplo 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()}");
        }
Aço azul
fonte