it-swarm.com.de

Deserialisierung von JSON in ein dynamisches C # -Objekt?

Gibt es eine Möglichkeit, JSON-Inhalte in einen dynamischen C # 4-Typ zu deserialisieren? Es wäre schön, wenn Sie das Erstellen mehrerer Klassen überspringen würden, um den DataContractJsonSerializer zu verwenden. 

839
jswanson

Wenn Sie froh sind, von der System.Web.Helpers Assembly abhängig zu sein, können Sie die Json class verwenden:

dynamic data = Json.Decode(json);

Es ist im MVC-Framework als zusätzlicher Download für das .NET 4-Framework enthalten. Seien Sie sicher, Vlad eine positive Bewertung zu geben, wenn dies hilfreich ist! Wenn Sie jedoch nicht davon ausgehen können, dass die Clientumgebung diese DLL enthält, lesen Sie weiter.


Ein alternativer Deserialisierungsansatz wird vorgeschlagen hier . Ich habe den Code leicht geändert, um einen Fehler zu beheben und meinem Kodierstil zu entsprechen. Sie benötigen lediglich diesen Code und einen Verweis auf System.Web.Extensions aus Ihrem Projekt:

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
}

Sie können es so verwenden:

string json = ...;

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

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

Also, eine JSON-Zeichenfolge gegeben:

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

Der folgende Code wird zur Laufzeit funktionieren:

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)
600
Drew Noakes

Es ist ziemlich einfach mit 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;

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

Dokumentation: JSON mit dynamischen Abfragen abfragen

540
Tom Peplow

Sie können dies mit System.Web.Helpers.Json - tun. Die Methode Decode gibt ein dynamisches Objekt zurück, das Sie nach Belieben durchsuchen können.

Es ist in der System.Web.Helpers-Assembly (.NET 4.0) enthalten.

var dynamicObject = Json.Decode(jsonString);
287
Vlad Iliescu

.NET 4.0 verfügt über eine integrierte Bibliothek, um dies auszuführen:

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

Dies ist der einfachste Weg.

78
Peter Long

Einfache "String-Json-Daten" zum Objekt ohne Drittanbieter-DLL

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 

Hinweis: Sie können auch Ihr benutzerdefiniertes Objekt verwenden. 

Personel item = serializer.Deserialize<Personel>(getString);
73

JsonFx kann Json in dynamische Objekte deserialisieren.

https://github.com/jsonfx/jsonfx

Serialize zu/von dynamischen Typen (Standard für .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]}
28
jbtule

Ich habe eine neue Version des DynamicJsonConverter erstellt, die Expando Objects verwendet. Ich habe expando-Objekte verwendet, weil ich die Dynamik mit Json.net in Json serialisieren wollte.

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) })); }
        }
    }
}  
18
Jason Bolton

Ein anderer Weg mit Newtonsoft.Json :

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

Der einfachste Weg ist 

Fügen Sie einfach diese dll

verwenden Sie den Code wie folgt

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.
7
user1006544

Sie können den JavaScriptSerializer erweitern, um das von ihm erstellte Wörterbuch rekursiv für expando-Objekte zu kopieren und dann dynamisch zu verwenden:

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

Dann brauchen Sie nur eine using-Anweisung für den Namespace, in dem Sie die Erweiterung definiert haben (Sie können sie nur in System.Web.Script.Serialization definieren. Ein weiterer Trick besteht darin, keinen Namespace zu verwenden. Dann brauchen Sie die Verwendung nicht Aussage), und Sie können sie wie folgt konsumieren:

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

Sie können using Newtonsoft.Json verwenden

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

resolvedEvent.Event.Data ist meine Antwort, die ich vom aufrufenden Core-Event bekomme.

6
Vivek Shukla

Ich benutze: http://json2csharp.com/ , Um eine Klasse zu erhalten, die das Json-Objekt darstellt.

Eingang:

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

Ausgabe:

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

Danach benutze ich Newtonsoft.Json , um die Klasse zu füllen:

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

Man kann es so nennen:

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

string stringJson = JObjects.Get(jsonClass);

PS: 

Wenn Ihr json-Variablenname kein gültiger C # -name ist (der Name beginnt mit $), können Sie das wie folgt beheben:

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

Dafür würde ich JSON.NET verwenden, um die Analyse des JSON-Streams auf niedriger Ebene durchzuführen und dann die Objekthierarchie aus Instanzen der ExpandoObject-Klasse aufzubauen.

5

Schauen Sie sich den Artikel an, den ich über CodeProject geschrieben habe. Dieser Artikel beantwortet die Frage genau:

Dynamische Typen mit JSON.NET

Es ist viel zu viel, um alles hier neu zu veröffentlichen, und noch weniger, da dieser Artikel einen Anhang mit dem Schlüssel/der erforderlichen Quelldatei hat.

5
vitaly-t

Ich verwende das so in meinem Code und es funktioniert gut

using System.Web.Script.Serialization;
JavaScriptSerializer oJS = new JavaScriptSerializer();
RootObject oRootObject = new RootObject();
oRootObject = oJS.Deserialize<RootObject>(Your JSon String);
5
Vasim Shaikh

Es gibt eine leichte Json-Bibliothek für C # namens SimpleJson, die Sie unter finden können http://simplejson.codeplex.com https://github.com/facebook-csharp-sdk/simple-json

Es unterstützt .net 3.5+, Silverlight und Windows Phone 7.

Unterstützt dynamisch für .net 4.0

Kann auch als Nuget-Paket installiert werden

Install-Package SimpleJson
4
prabir

Die Deserialisierung in JSON.NET kann mit der in dieser Bibliothek enthaltenen JObject-Klasse dynamisch sein. Mein JSON-String steht für diese Klassen:

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

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

Jetzt deserialisieren wir die Zeichenfolge, OHNE auf die obigen Klassen zu verweisen:

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

Oder wenn Sie tiefer gehen wollen:

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

Siehe post für ein vollständiges Beispiel.

4
Chad Kuehn

verwendung von DataSet (C #) Mit Javascript Einfache Funktion zum Erstellen eines Json-Streams mit DataSet-Eingabe Erstellen Sie Json Like (Multi-Table-Dataset) [[{a: 1, b: 2, c: 3} a: 3, b: 5, c: 6}], [{a: 23, b: 45, c: 35}, {a: 58, b: 59, c: 45}]]

nur clientseitige Verwendung eval zum Beispiel

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

dann benutze 

d [0] [0] .a // out 1 aus Tabelle 0 Reihe 0

d [1] [1] .b // out 59 aus Tabelle 1 Reihe 1

//create by Behnam Mohammadi And Saeed Ahmadian
public string jsonMini(DataSet ds)
{
    int t=0, r=0, c=0;
    string stream = "[";

    for (t = 0; t < ds.Tables.Count; t++)
    {
        stream += "[";
        for (r = 0; r < ds.Tables[t].Rows.Count; r++)
        {
            stream += "{";
            for (c = 0; c < ds.Tables[t].Columns.Count; c++)
            {
                stream += ds.Tables[t].Columns[c].ToString() + ":'" + ds.Tables[t].Rows[r][c].ToString() + "',";
            }
            if(c>0)
                stream = stream.Substring(0, stream.Length - 1);
            stream += "},";
        }
        if(r>0)
            stream = stream.Substring(0, stream.Length - 1);
        stream += "],";
    }
    if(t>0)
        stream = stream.Substring(0, stream.Length - 1);
    stream += "];";
    return stream;
}
4

versuche dies - 

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

Es ist wahrscheinlich etwas spät, um Ihnen zu helfen, aber das gewünschte Objekt DynamicJSONObject ist in der Datei System.Web.Helpers.dll aus dem ASP.NET Web Pages-Paket enthalten, das Teil von WebMatrix ist.

4
Nick Daniels

So erhalten Sie ein ExpandoObject:

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

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

So analysieren Sie Easy Json mit Dynamic & JavaScriptSerializer

Bitte fügen Sie einen Verweis auf System.Web.Extensions hinzu und fügen Sie diesen Namespace using System.Web.Script.Serialization; oben ein

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

Wie man verschachtelte & komplexe Json mit dynamischem & JavaScriptSerializer analysiert

Bitte fügen Sie einen Verweis auf System.Web.Extensions hinzu und fügen Sie diesen Namespace using System.Web.Script.Serialization; oben ein

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

Das können Sie mit Hilfe von Newtonsoft.Json erreichen. Installieren Sie Newtonsoft.Json von Nuget und das:

using Newtonsoft.Json;

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

Eine weitere Option ist das "Einfügen von JSON als Klassen", damit es schnell und einfach deserialisiert werden kann.

  1. Kopieren Sie einfach Ihre gesamte JSON
  2. In VS: Klicken Sie auf Bearbeiten> Inhalte einfügen> JSON als Klassen einfügen

Hier ist eine bessere Erklärung n piccas ... https://blogs.msdn.Microsoft.com/webdev/2012/12/18/paste-json-as-classes-in-asp-net-and-web- tools-2012-2-rc/

1
nitsram

versuche es auf diese Weise!

JSON-Beispiel:

  [{
            "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 # -Code:

        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()}");
        }
0
Blue Steel

Mit Cinchoo ETL - einer Open Source-Bibliothek, die Json in dynamisches Objekt parsen kann

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: " + rec.ip);
    }
}

Ausgabe:

action: open
timestamp: 2018-09-05 20:46:00
url: http://www.google.com
ip: 66.102.6.98

Haftungsausschluss: Ich bin der Autor dieser Bibliothek.

0
RajN