Désérialiser JSON en objet dynamique C #?

966

Existe-t-il un moyen de désérialiser le contenu JSON en un type dynamique C # 4? Ce serait bien de sauter la création d'un tas de classes pour utiliser le DataContractJsonSerializer.

jswanson
la source
5
Si vous voulez quelque chose de «dynamique», pourquoi ne pas simplement utiliser les accesseurs de style get fournis avec la plupart des décodeurs JSON qui ne vont pas à plain-old-object? (par exemple, existe-t-il vraiment un besoin de création d'objet «dynamique»?) json.org a un tas de liens pour les implémentations C # JSON.
Je travaille sur un projet qui essaie de réduire au minimum les dépendances externes. Donc, s'il est possible de trouver quelque chose avec les sérialiseurs .net et les types qui seraient préférés. Bien sûr, si ce n'est pas possible, je lance json.org. Merci!
jswanson
42
Je suis vraiment surpris que l'équipe C # ait ajouté «dynamique», mais il n'y a aucun moyen dans le CLR de convertir un objet JSON en une instance de classe CLR dynamique.
Frank Schwieterman
2
Malheureusement, la réponse acceptée ne fonctionne pas dans .NET 4 RTM. J'ai posté une réponse qui m'a aidé à aller de l'avant et qui pourrait être utile à d'autres.
Drew Noakes
(Bien qu'il semble que Newtonsoft JSON.NET se rapproche assez. Il n'y a pas vraiment de bons exemples, cependant.)
Hot Licks

Réponses:

660

Si vous êtes satisfait d'avoir une dépendance sur l' System.Web.Helpersassembly, vous pouvez utiliser la Jsonclasse:

dynamic data = Json.Decode(json);

Il est inclus avec le framework MVC en tant que téléchargement supplémentaire du framework .NET 4. Assurez-vous de donner une note positive à Vlad si cela est utile! Cependant, si vous ne pouvez pas supposer que l'environnement client inclut cette DLL, poursuivez votre lecture.


Une approche alternative de désérialisation est suggérée ici . J'ai légèrement modifié le code pour corriger un bug et convenir à mon style de codage. Tout ce dont vous avez besoin est ce code et une référence à System.Web.Extensionsvotre projet:

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
}

Vous pouvez l'utiliser comme ceci:

string json = ...;

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

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

Donc, étant donné une chaîne JSON:

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

Le code suivant fonctionnera lors de l'exécution:

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
la source
1
J'obtiens une erreur dans obj = serializer.Deserialize dynamique (json, typeof (object)); disant qu'il n'y a pas de surcharge pour la méthode avec 2 arguments..dll erronée ou quoi?
Stewie Griffin
32
Vous pouvez utiliser System.Web.Helpers.Json - il propose une méthode Decode qui renvoie un objet dynamique. J'ai également posté cette information comme réponse.
Vlad Iliescu
2
Cela m'a également beaucoup aidé, mais je suis curieux de savoir ce que je dois faire si j'ai besoin d'utiliser la méthode .Serialize, qui ne génère actuellement qu'une exception NotImplementedException ... Je ne suis pas trop familier avec les classes scellées et / ou le résumé étendu Des classes. Est-ce que quelqu'un peut-il me montrer la bonne direction?
Cory W.
2
parfois en js vous avez des champs avec des caractères spéciaux comme "background-color". Pour accéder à ces champs dans js, vous devez obj ["background-color"]. Comment puis-je accéder à ces champs à partir de c # après la désérialisation en objet dynamique? Je ne peux pas faire obj.background-color, bien sûr, et obj ["background-color"] ne semble pas fonctionner. Ce serait bien si l'objet dynamique pouvait également être consulté en tant que dictionnaire, en même temps, exactement comme dans js.
Radu Simionescu
2
@RaduSimionescu Je suis probablement un peu en retard, mais cela aide peut-être les futurs visiteurs. J'ai eu le même problème, juste avec le nom de champ params(qui est un mot-clé en C #). De plus, TryGetMembervous pouvez remplacer TryGetIndex, ce qui vous donne exactement le même comportement que dans JS. Ensuite, vous pouvez faire obj["params"]ou obj["background-color"]pour les noms de champs maladroits.
Martin Ender
606

C'est assez simple en utilisant 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;

Aussi 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: requête JSON avec dynamique

Tom Peplow
la source
9
@HotLicks: Pour introspecter la dynamique, stufffaites quelque chose comme:foreach (Newtonsoft.Json.Linq.JProperty jproperty in stuff) { Console.WriteLine("jproperty.Name = {0}", jproperty.Name);}
Matthias
11
Quelle est la différence entre JsonConvert.DeserializeObject et JObject.Parse? La réponse est de les utiliser tous les deux de la même manière pour faire la même chose mais n'explique pas la différence.
cja
7
@TomPeplow J'ai essayé cela. Ça n'a pas marché pour moi. Il indique que "JObject n'implémente pas 'Nom'".
Lee Louviere
4
@cja pas de différence: stackoverflow.com/questions/23645034/…
nawfal
8
Je ne peux pas faire fonctionner ça. J'ai réduit le problème à l'intérieur d'une asyncméthode. Si je rend la méthode synchrone, elle fonctionne comme prévu. Cependant, faites la méthode asyncet je ne peux pas obtenir un dynamic, je reçois juste un object. Le casting explicite ne fait rien, me donne toujours un object. Quelqu'un d'autre rencontre ce problème?
codeConcussion
295

Vous pouvez le faire en utilisant System.Web.Helpers.Json - sa méthode Decode renvoie un objet dynamique que vous pouvez parcourir à votre guise.

Il est inclus dans l'assembly System.Web.Helpers (.NET 4.0).

var dynamicObject = Json.Decode(jsonString);
Vlad Iliescu
la source
25
FYI System.Web.Helpers.dll nécessite .net 4.0 mais n'est pas inclus dans .net 4.0. Il peut être installé avec ASP.NET MVC 3
jbtule
7
Vous trouverez cet assembly dans le groupe Extensions sous Assemblys dans Visual Studio 2012
W3Max
1
Des problèmes avec l'utilisation dynamique? Comment pouvons-nous gérer les exceptions efficacement si l'entrée JSON ne contient pas les propriétés ..
Usama Khalil
5
Si vous souhaitez taper fortement le modèle, assurez-vous d'utiliser la méthode Json.Decode <T> (chaîne).
Mike
2
Pour ajouter cette bibliothèque à votre projet: stackoverflow.com/questions/8037895/…
80

.NET 4.0 dispose d'une bibliothèque intégrée pour ce faire:

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

C'est le moyen le plus simple.

Peter Long
la source
27
avez-vous essayé cela? Il revient Dictionary<string,object>. Sauf si je manque quelque chose, votre exemple ne renvoie pas d'objet dynamique.
sergiopereira
18
Cela ne fonctionne pas, il renvoie simplement un dict sous la forme d'une dynamique
mattmanser
55
@Peter Long Je crois que je n'ai pas exposé clairement mon cas, cher ami. Permettez-moi d'essayer de rectifier mon erreur. Je sais ce qu'est une dynamique. Cela ne vous permet pas de passer un objet JSON et d'utiliser d.code, vous devez faire d ["code"]. Valeur, ce qui n'est pas ce que la plupart des gens recherchent cette réponse, nous savons déjà comment obtenir le dictionnaire et le convertir en une dynamique est une perte de temps totale. Je ne suis respectueusement pas d'accord, monsieur.
mattmanser
4
@mattmanser, we already know how to get the dictionary and casting it to a dynamic. Il n'est pas nécessaire que ce soit un dictionnaire. Json a également des listes en plus du dictionnaire. Et aussi des listes et des dictionnaires pourraient être imbriqués. Mon code pourrait gérer toutes ces situations. MAIS votre méthode ne peut PAS.
Peter Long
4
@mattmanser a raison; il est possible d'implémenter IDynamicMetaObjectProvider(ou d'utiliser par exemple ExpandoObject) qui est capable d'intercepter des propriétés et de les rechercher dans un dictionnaire interne. Ceci combiné avec l'utilisation de dynamicpermet un code tel qu'il d.codesoit utilisé. Il est inutile de convertir un dictionnaire en une dynamique.
Stephen Drew
78

"Chaîne de données JSON" simple pour s'opposer sans aucun fichier DLL tiers:

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

Remarque: vous pouvez également utiliser votre objet personnalisé.

Personel item = serializer.Deserialize<Personel>(getString);
İbrahim Özbölük
la source
4
Je ne comprends pas. C'est de loin la solution la plus simple et personne ne la mentionne.
cikatomo
2
oui c'est simple :) parfois vous avez besoin de sérialiser mais vous ne voulez pas inclure la dll de la troisième partie
İbrahim Özbölük
Pouvez - vous préciser: comment dynamique peut accéder à l'objet désérialisé via: myObject["myprop"]? Je sais que c'est fait à l'exécution, mais comment y accéder via myObject["myprop"]est-il valide?
Royi Namir
1
Vous pouvez désérialiser votre objet comme Personel item = serializer.Deserialize <Personel> (getString); et si vous utilisez un objet dynamique, vous pouvez également utiliser un tableau et tout est possible comme everyobject
İbrahim Özbölük
3
Pour utiliser l'espace de noms System.Web.Script.Serialization, votre projet a besoin d'une référence à System.Web.Extensions.
StilgarISCA
28

JsonFx peut désérialiser le contenu JSON en objets dynamiques.

Sérialiser vers / depuis les types dynamiques (par défaut pour .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
la source
19

J'ai créé une nouvelle version du DynamicJsonConverter qui utilise des objets Expando. J'ai utilisé des objets expando, car je voulais sérialiser la dynamique en JSON à l'aide de 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
la source
18

Une autre façon d'utiliser Newtonsoft.Json :

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

Vous pouvez y parvenir avec l'aide de Newtonsoft.Json. Installez Newtonsoft.Json à partir de Nuget et:

using Newtonsoft.Json;

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

La manière la plus simple est:

Incluez simplement ce fichier DLL .

Utilisez le code comme ceci:

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
la source
6

Vous pouvez étendre JavaScriptSerializer pour copier récursivement le dictionnaire qu'il a créé pour développer des objets, puis les utiliser dynamiquement:

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

Ensuite, il vous suffit d'avoir une instruction using pour l'espace de noms dans lequel vous avez défini l'extension (pensez simplement à les définir dans System.Web.Script.Serialization ... une autre astuce consiste à ne pas utiliser d'espace de noms, alors vous n'avez pas besoin de l'utilisation de du tout) et vous pouvez les consommer comme ceci:

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
la source
6

Vous pouvez utiliser using Newtonsoft.Json

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

resolvedEvent.Event.Data est ma réponse en appelant l'événement de base.

Vivek Shukla
la source
6

J'utilise http://json2csharp.com/ pour obtenir une classe représentant l'objet JSON.

Contribution:

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

Production:

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

Après cela, j'utilise Newtonsoft.Json pour remplir la 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);
        }
    }
}

Vous pouvez l'appeler comme ceci:

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

string stringJson = JObjects.Get(jsonClass);

PS:

Si le nom de votre variable JSON n'est pas un nom C # valide (le nom commence par $), vous pouvez corriger cela comme ceci:

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
la source
5

Pour cela, j'utiliserais JSON.NET pour effectuer l'analyse de bas niveau du flux JSON, puis créer la hiérarchie d'objets à partir des instances de la ExpandoObjectclasse.

Daniel Earwicker
la source
5

J'utilise comme ça dans mon code et ça marche bien

using System.Web.Script.Serialization;
JavaScriptSerializer oJS = new JavaScriptSerializer();
RootObject oRootObject = new RootObject();
oRootObject = oJS.Deserialize<RootObject>(Your JSon String);
Vasim Shaikh
la source
1
mais ce n'est pas le sujet de la question. il y a une différence lorsque vous devez spécifier le type de chaque chaîne json et travailler avec un type dynamique.
Illuminati
5

Regardez l'article que j'ai écrit sur CodeProject, qui répond précisément à la question:

Types dynamiques avec JSON.NET

Il y a beaucoup trop de choses à republier ici, et encore moins de points puisque cet article a une pièce jointe avec la clé / le fichier source requis.

vitaly-t
la source
5

Une autre option consiste à "Coller JSON en tant que classes" afin qu'il puisse être désérialisé rapidement et facilement.

  1. Copiez simplement l'intégralité de votre JSON
  2. Dans Visual Studio: cliquez sur ÉditionCollage spécialColler JSON en tant que classes

Voici une meilleure explication n piccas ... 'Coller JSON comme classes' dans ASP.NET et Web Tools 2012.2 RC

nitsram
la source
cela m'a fait gagner beaucoup de temps! devrait être choisi comme meilleure réponse!
jsiot
4

La désérialisation dans JSON.NET peut être dynamique à l'aide de la JObjectclasse, qui est incluse dans cette bibliothèque. Ma chaîne JSON représente ces classes:

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

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

Désérialisons maintenant la chaîne SANS référencer les classes ci-dessus:

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 si vous voulez aller plus loin:

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

Voir l' article pour un exemple complet.

Chad Kuehn
la source
Cette approche permet de "parcourir" le document jSON, de sorte que vous puissiez gérer une situation où la structure JSON est inconnue ou variable (par exemple, de nombreuses API retournent un document JSON complètement différent lorsqu'une erreur se produit). Il existe d'autres bibliothèques qui permettent de le faire, à part Newtonsoft.JSON (alias JSON.NET)?
Alex 75
4

L'objet souhaité DynamicJSONObject est inclus dans System.Web.Helpers.dll à partir du package de pages Web ASP.NET, qui fait partie de WebMatrix.

Nick Daniels
la source
4

Il existe une bibliothèque JSON légère pour C # appelée SimpleJson .

Il prend en charge .NET 3.5+, Silverlight et Windows Phone 7.

Il prend en charge dynamique pour .NET 4.0

Il peut également être installé en tant que package NuGet

Install-Package SimpleJson
prabir
la source
4

Utilisez DataSet (C #) avec JavaScript. Une fonction simple pour créer un flux JSON avec une entrée DataSet. Créez du contenu JSON comme (ensemble de données multi-tables):

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

Côté client, utilisez eval. Par exemple,

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

Utilisez ensuite:

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
la source
3

Pour obtenir un ExpandoObject:

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

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

Essaye ça:

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

Comment analyser du contenu JSON facile avec DynamicSerializer et JavaScript

Veuillez ajouter la référence de System.Web.Extensions et ajouter cet espace using System.Web.Script.Serialization;de noms en haut:

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

Comment analyser un json imbriqué et complexe avec dynamic & JavaScriptSerializer

Veuillez ajouter la référence de System.Web.Extensions et ajouter cet espace using System.Web.Script.Serialization;de noms en haut:

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();
}
Brouillard
la source
1

Avec Cinchoo ETL - une bibliothèque open source disponible pour analyser JSON dans un objet dynamique:

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

Production:

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

Avertissement: je suis l'auteur de cette bibliothèque.

RajN
la source
0

essayez de cette façon!

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

Code 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()}");
        }
Blue Steel
la source