[c#] Désérialise JSON en objet dynamique C #?



10 Answers

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

using Newtonsoft.Json.Linq 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: interrogation de JSON avec dynamique

Question

Y at-il un moyen de désérialiser le contenu JSON dans un type dynamique C # 4? Ce serait bien d'ignorer la création d'un tas de classes pour utiliser DataContractJsonSerializer.







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



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;



Il y a une bibliothèque json légère pour C # appelée SimpleJson qui peut être trouvée à http://simplejson.codeplex.com https://github.com/facebook-csharp-sdk/simple-json

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

Prend en charge la dynamique pour .net 4.0

Peut également être installé comme un paquet de nuget

Install-Package SimpleJson



Vous pouvez utiliser en using Newtonsoft.Json

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

resolvedEvent.Event.Data est ma réponse obtenant de l'appel de l'événement principal.




La désérialisation dans JSON.NET peut être dynamique en utilisant la classe JObject , 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;}
}

Maintenant, nous désérialisons 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 post pour un exemple complet.




Vous pouvez étendre le JavaScriptSerializer pour copier récursivement le dictionnaire qu'il a créé pour les objets expando, 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, vous avez juste besoin 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 un espace de noms, vous n'avez pas besoin d'utiliser déclaration du tout) et vous pouvez les consommer comme ça:

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



Pour obtenir un ExpandoObject:

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

Container container = JsonConvert.Deserialize<Container>(jsonAsString, new ExpandoObjectConverter());



.Net 4.0 a 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.




JsonFx peut désérialiser json dans des objets dynamiques.

https://github.com/jsonfx/jsonfx

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



Related