Gibt es eine Möglichkeit, JSON-Inhalte in einen dynamischen C#-Typ zu deserialisieren? Es wäre schön, wenn man die Erstellung einer Reihe von Klassen überspringen könnte, um die DataContractJsonSerializer
.
Antworten
Zu viele Anzeigen?Ich kam hierher, um eine Antwort für .NET Core zu finden, ohne Drittanbieter oder zusätzliche Referenzen. Es funktioniert gut, wenn Sie verwenden ExpandoObject
mit dem Standard JsonSerializer
Klasse. Hier ist das Beispiel, das bei mir funktioniert hat:
using System.Text.Json;
using System.Dynamic;
dynamic json = JsonSerializer.Deserialize<ExpandoObject>(jsonText);
Console.WriteLine(json.name);
Dieser Code gibt den Zeichenfolgenwert einer Namenseigenschaft aus, die in dem JSON-Text vorhanden ist, der an die Deserialize
Methode. Voila - keine zusätzlichen Bibliotheken, kein Nichts. Nur .NET Core.
Edit : Bei mehreren Ebenen von json mit verschachtelten Elementen kann ein Problem auftreten. Funktioniert bei einem einstufigen flachen Objekt.
Ich benutze http://json2csharp.com/ um eine Klasse zu erhalten, die das JSON-Objekt repräsentiert.
Eingabe:
{
"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 verwende 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 der Name Ihrer JSON-Variable kein gültiger C#-Name ist (der Name beginnt mit $
), können Sie das 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; }
}
Das ist der einfachste Weg:
Fügen Sie einfach Folgendes hinzu DLL-Datei .
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.
Eine weitere Möglichkeit ist "JSON als Klassen einfügen" damit es schnell und einfach deserialisiert werden kann.
- Kopieren Sie einfach Ihr gesamtes JSON
- In Visual Studio: Klicken Sie auf . Edit → Einfügen Spezial → JSON 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
Sie können den JavaScriptSerializer erweitern, um das von ihm erstellte Wörterbuch rekursiv in expando-Objekte zu kopieren und diese 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 zu haben, in dem Sie die Erweiterung definiert haben (erwägen Sie, sie einfach in System.Web.Script.Serialization zu definieren... ein anderer Trick ist, keinen Namespace zu verwenden, dann brauchen Sie die using-Anweisung überhaupt nicht) 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