JSON in dynamisches C # -Objekt deserialisieren?

965

Gibt es eine Möglichkeit, JSON-Inhalte in einen dynamischen C # 4-Typ zu deserialisieren? Es wäre schön, das Erstellen einer Reihe von Klassen zu überspringen, um die zu verwenden DataContractJsonSerializer.

jswanson
quelle
5
Wenn Sie etwas 'Dynamisches' wollen, warum nicht einfach die Get-Style-Accessoren verwenden, die mit den meisten JSON-Decodern geliefert werden, die nicht zu einfachen alten Objekten gehören? (zB besteht wirklich Bedarf an 'dynamischer' Objekterstellung?) json.org verfügt über eine Reihe von Links für C # JSON-Implementierungen.
Ich arbeite an einem Projekt, das versucht, externe Abhängigkeiten auf ein Minimum zu beschränken. Also, wenn es möglich ist, etwas mit den serienmäßigen .net-Serialisierern und -Typen zu tun, die bevorzugt würden. Wenn es nicht möglich ist, melde ich mich natürlich bei json.org. Vielen Dank!
Jswanson
42
Ich bin wirklich überrascht, dass das C # -Team 'dynamic' hinzugefügt hat, aber dann gibt es in der CLR keine Möglichkeit, ein JSON-Objekt in eine dynamische CLR-Klasseninstanz zu konvertieren.
Frank Schwieterman
2
Leider funktioniert die akzeptierte Antwort in .NET 4 RTM nicht. Ich habe eine Antwort gepostet, die mir dabei geholfen hat, die für andere nützlich sein könnte.
Drew Noakes
(Obwohl es scheint, dass Newtonsoft JSON.NET ziemlich nahe kommt. Es gibt jedoch keine wirklich guten Beispiele.)
Hot Licks

Antworten:

659

Wenn Sie froh sind, eine Abhängigkeit von der System.Web.HelpersAssembly zu haben, können Sie die JsonKlasse verwenden:

dynamic data = Json.Decode(json);

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


Ein alternativer Deserialisation Ansatz wird vorgeschlagen , hier . Ich habe den Code leicht geändert, um einen Fehler zu beheben und meinem Codierungsstil zu entsprechen. Sie benötigen lediglich diesen Code und einen Verweis auf System.Web.ExtensionsIhr 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, gegeben eine JSON-Zeichenfolge:

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

Der folgende Code funktioniert zur Laufzeit:

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
quelle
1
Ich erhalte einen Fehler in dynamic obj = serializer.Deserialize (json, typeof (object)); sagen, dass keine Überladung für Methode mit 2 Argumenten .. falsche DLL oder was?
Stewie Griffin
32
Sie können System.Web.Helpers.Json verwenden - es bietet eine Decode-Methode, die ein dynamisches Objekt zurückgibt. Ich habe diese Informationen auch als Antwort gepostet.
Vlad Iliescu
2
Das hat mir auch sehr geholfen, aber ich bin gespannt, was ich tun soll, wenn ich die .Serialize-Methode verwenden muss, die derzeit nur eine NotImplementedException auslöst ... Ich bin mit versiegelten Klassen und / oder erweiterten Abstracts nicht allzu vertraut Klassen. Kann mich jemand in die richtige Richtung weisen?
Cory W.
2
manchmal haben Sie in js Felder mit Sonderzeichen wie "Hintergrundfarbe". Um auf solche Felder in js zuzugreifen, tun Sie obj ["Hintergrundfarbe"]. Wie kann ich nach dem Deserialisieren auf ein dynamisches Objekt von c # aus auf solche Felder zugreifen? Ich kann natürlich keine obj.background-color machen und obj ["background-color"] scheint nicht zu funktionieren. Es wäre schön, wenn auf das dynamische Objekt gleichzeitig auch als Wörterbuch zugegriffen werden könnte, genau wie in js.
Radu Simionescu
2
@RaduSimionescu Ich bin wahrscheinlich etwas spät dran, aber vielleicht hilft dies zukünftigen Besuchern. Ich hatte das gleiche Problem, nur mit dem Feldnamen params(der ein Schlüsselwort in C # ist). Außerdem TryGetMemberkönnen Sie überschreiben TryGetIndex, wodurch Sie genau das gleiche Verhalten wie in JS erhalten. Dann können Sie obj["params"]oder obj["background-color"]für umständliche Feldnamen.
Martin Ender
606

Mit Json.NET ist das ganz einfach :

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: Abfrage von JSON mit Dynamic

Tom Peplow
quelle
9
@ HotLicks: Um die Dynamik zu überprüfen, stuffmachen Sie etwas wie:foreach (Newtonsoft.Json.Linq.JProperty jproperty in stuff) { Console.WriteLine("jproperty.Name = {0}", jproperty.Name);}
Matthias
11
Was ist der Unterschied zwischen JsonConvert.DeserializeObject und JObject.Parse? Die Antwort ist, beide auf die gleiche Weise zu verwenden, um dasselbe zu tun, aber den Unterschied nicht zu erklären.
Cja
7
@ TomPeplow Versuchte dies. Bei mir hat es nicht funktioniert. Es heißt, dass "JObject 'Name' nicht implementiert".
Lee Louviere
4
@ Cja kein Unterschied: Stackoverflow.com/questions/23645034/…
Nawfal
8
Ich kann das nicht zum Laufen bringen. Ich habe das Problem auf eine asyncMethode eingegrenzt. Wenn ich die Methode synchronisiere, funktioniert sie wie erwartet. Allerdings mache die Methode asyncund ich kann keine bekommen dynamic, ich bekomme nur eine object. Explizites Casting macht nichts, gibt mir immer noch nur eine object. Erlebt das noch jemand?
CodeConcussion
295

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

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

var dynamicObject = Json.Decode(jsonString);
Vlad Iliescu
quelle
25
FYI System.Web.Helpers.dll erfordert .net 4.0, ist jedoch nicht in .net 4.0 enthalten. Es kann mit ASP.NET MVC 3 installiert werden
jbtule
7
Sie finden diese Assembly in der Gruppe Erweiterungen unter Assemblies in Visual Studio 2012
W3Max
1
Probleme bei der Verwendung von Dynamic? Wie können wir Ausnahmen effizient behandeln, wenn Eingabe JSON nicht die Eigenschaften enthält ..
Usama Khalil
5
Wenn Sie das Modell stark eingeben möchten, müssen Sie die Methode Json.Decode <T> (Zeichenfolge) verwenden.
Mike
2
So fügen Sie diese Bibliothek Ihrem Projekt hinzu: stackoverflow.com/questions/8037895/…
80

.NET 4.0 verfügt über eine integrierte Bibliothek, um dies zu tun:

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

Dies ist der einfachste Weg.

Peter Long
quelle
27
hast du das versucht Es kehrt zurück Dictionary<string,object>. Sofern mir nichts fehlt, gibt Ihr Beispiel kein dynamisches Objekt zurück.
Sergiopereira
18
Dies funktioniert nicht, es gibt nur ein Diktat in Form eines dynamischen
Mattmanser
55
@ Peter Long Ich glaube, ich habe meinen Fall nicht klar dargelegt, lieber Kerl. Lassen Sie mich versuchen, meinen Fehler zu beheben. Ich weiß, was eine Dynamik ist. Dies erlaubt Ihnen nicht, ein JSON-Objekt zu übergeben und d.code zu verwenden. Sie müssten d ["code"] ausführen. Wert, den die meisten Leute, die diese Antwort finden, nicht wollen, wissen wir bereits Das Wörterbuch zu bekommen und es in eine Dynamik umzuwandeln, ist reine Zeitverschwendung. Ich bin respektvoll anderer Meinung, Sir.
Mattmanser
4
@mattmanser , we already know how to get the dictionary and casting it to a dynamic. Es muss kein Wörterbuch sein. Json hat neben dem Wörterbuch auch Listen. Außerdem können Listen und Wörterbücher verschachtelt werden. Mein Code könnte all diese Situationen bewältigen. ABER Ihre Methode kann NICHT.
Peter Long
4
@ Mattmanser ist richtig; Es ist möglich, Eigenschaften zu implementieren IDynamicMetaObjectProvider(oder zu verwenden ExpandoObject), die in der Lage sind, Eigenschaften abzufangen und in einem internen Wörterbuch nachzuschlagen. Dies in Kombination mit der Verwendung von dynamicermöglicht die Verwendung von Code d.code. Es ist irgendwie sinnlos, ein Wörterbuch in eine Dynamik umzuwandeln.
Stephen Drew
78

Einfache "String-JSON-Daten" zum Objektieren ohne DLL-Datei eines Drittanbieters:

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);
İbrahim Özbölük
quelle
4
Ich verstehe es nicht. Dies ist bei weitem die einfachste Lösung, und niemand erwähnt sie.
Cikatomo
2
Ja, es ist einfach :) Manchmal müssen Sie serialisieren, möchten aber nicht die dritte Teil-DLL
einschließen
Können Sie näher erläutern: Wie dynamisch kann auf das DEserialized-Objekt zugegriffen werden über : myObject["myprop"]? Ich weiß, dass es zur Laufzeit gemacht wird, aber wie ist der Zugriff darauf myObject["myprop"]gültig?
Royi Namir
1
Sie können Ihr Objekt wie Personel item = serializer deserialisieren. Deserialize <Personel> (getString); und wenn Sie ein dynamisches Objekt verwenden, können Sie auch ein Array verwenden und alles ist möglich wie bei jedem Objekt
İbrahim Özbölük
3
Um den System.Web.Script.Serialization-Namespace verwenden zu können, benötigt Ihr Projekt einen Verweis auf System.Web.Extensions.
StilgarISCA
28

JsonFx kann JSON-Inhalte in dynamische Objekte deserialisieren.

Serialisieren 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]}
jbtule
quelle
19

Ich habe eine neue Version des DynamicJsonConverter erstellt, die Expando-Objekte verwendet. Ich habe expando-Objekte verwendet, weil ich die Dynamik mithilfe von Json.NET wieder 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) })); }
        }
    }
}
Jason Bolton
quelle
18

Eine andere Möglichkeit, Newtonsoft.Json zu verwenden :

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

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

using Newtonsoft.Json;

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

Der einfachste Weg ist:

Fügen Sie einfach diese DLL-Datei hinzu .

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

Sie können den JavaScriptSerializer erweitern, um das erstellte Wörterbuch rekursiv zu kopieren, um Objekte zu erweitern, und sie 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 noch eine using-Anweisung für den Namespace, in dem Sie die Erweiterung definiert haben (definieren Sie sie einfach in System.Web.Script.Serialization ... ein weiterer Trick besteht darin, keinen Namespace zu verwenden, dann brauchen Sie die using nicht Aussage überhaupt) und Sie können sie so 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
Alonzofox
quelle
6

Sie können verwenden using Newtonsoft.Json

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

resolvedEvent.Event.Data ist meine Antwort vom Aufrufen des Kernereignisses.

Vivek Shukla
quelle
6

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

Sie können 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 (Name beginnt mit $), können Sie dies folgendermaßen 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; }
}
RoJaIt
quelle
5

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

Daniel Earwicker
quelle
5

Ich verwende 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);
Vasim Shaikh
quelle
1
Aber darum geht es in der Frage nicht. Es gibt eine andere Möglichkeit, wenn Sie den Typ für jede JSON-Zeichenfolge angeben und mit dem dynamischen Typ arbeiten müssen.
Illuminati
5

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

Dynamische Typen mit JSON.NET

Es gibt viel zu viel, um alles hier erneut zu veröffentlichen, und noch weniger Sinn, da dieser Artikel einen Anhang mit dem Schlüssel / der erforderlichen Quelldatei enthält.

vitaly-t
quelle
5

Eine andere Option ist "JSON als Klassen einfügen", damit es schnell und einfach deserialisiert werden kann.

  1. Kopieren Sie einfach Ihren gesamten JSON
  2. In Visual Studio: Klicken Sie auf BearbeitenInhalte einfügenJSON als Klassen einfügen

Hier ist eine bessere Erklärung n piccas ... 'JSON als Klassen einfügen ' in ASP.NET und Web Tools 2012.2 RC

Nitsram
quelle
das hat mir viel zeit gespart! sollte als beste Antwort gewählt werden!
jsiot
4

Das Deserialisieren in JSON.NET kann mithilfe der JObjectKlasse, die in dieser Bibliothek enthalten ist, dynamisch sein . Meine JSON-Zeichenfolge repräsentiert 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 den String, 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());

Ein vollständiges Beispiel finden Sie im Beitrag .

Chad Kuehn
quelle
Dieser Ansatz ermöglicht das "Durchlaufen" des jSON-Dokuments, sodass Sie Situationen verwalten können, in denen die JSON-Struktur unbekannt oder variabel ist (z. B. geben viele APIs bei Auftreten eines Fehlers ein völlig anderes JSON-Dokument zurück). Abgesehen von Newtonsoft.JSON (auch bekannt als JSON.NET) gibt es andere Bibliotheken, die dies zulassen?
Alex 75
4

Das gewünschte Objekt DynamicJSONObject ist in der System.Web.Helpers.dll aus dem ASP.NET-Webseitenpaket enthalten, das Teil von WebMatrix ist.

Nick Daniels
quelle
4

Es gibt eine leichtgewichtige JSON-Bibliothek für C # SimpleJson .

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

Es unterstützt Dynamic für .NET 4.0

Es kann auch als NuGet-Paket installiert werden

Install-Package SimpleJson
Prabir
quelle
4

Verwenden Sie DataSet (C #) mit JavaScript. Eine einfache Funktion zum Erstellen eines JSON-Streams mit DataSet-Eingabe. Erstellen Sie JSON-Inhalte wie (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 Client-Seite, verwenden Sie 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 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
quelle
3

So erhalten Sie ein ExpandoObject:

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

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

Versuche dies:

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

So analysieren Sie einfache JSON-Inhalte mit Dynamic & JavaScriptSerializer

Bitte fügen Sie die Referenz von System.Web.Extensions hinzu und fügen Sie diesen Namespace using System.Web.Script.Serialization;oben hinzu:

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

So analysieren Sie verschachtelte und komplexe JSON mit Dynamic & JavaScriptSerializer

Bitte fügen Sie die Referenz von System.Web.Extensions hinzu und fügen Sie diesen Namespace using System.Web.Script.Serialization;oben hinzu:

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

Mit Cinchoo ETL - einer Open Source-Bibliothek, mit der JSON in ein dynamisches Objekt analysiert werden 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 address: " + rec.ip);
    }
}

Ausgabe:

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

Haftungsausschluss: Ich bin der Autor dieser Bibliothek.

RajN
quelle
0

versuche es so!

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()}");
        }
Blauer Stahl
quelle