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
.
- Wie kann ich JSON mit C# deserialisieren? (18 Antworten )
Antworten
Zu viele Anzeigen?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
Die Deserialisierung in JSON.NET kann dynamisch erfolgen, indem die JObject
Klasse, die in dieser Bibliothek enthalten ist. Mein JSON-String 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 die Zeichenkette OHNE Verweis auf die oben genannten Klassen:
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 Beitrag für ein vollständiges Beispiel.