Czy możliwe jest zwrócenie obiektu dynamicznego z deserializacji json przy użyciu json.net? Chciałbym zrobić coś takiego:
dynamic jsonResponse = JsonConvert.Deserialize(json);
Console.WriteLine(jsonResponse.message);
Czy możliwe jest zwrócenie obiektu dynamicznego z deserializacji json przy użyciu json.net? Chciałbym zrobić coś takiego:
dynamic jsonResponse = JsonConvert.Deserialize(json);
Console.WriteLine(jsonResponse.message);
Odpowiedzi:
Json.NET pozwala nam to zrobić:
dynamic d = JObject.Parse("{number:1000, str:'string', array: [1,2,3,4,5,6]}");
Console.WriteLine(d.number);
Console.WriteLine(d.str);
Console.WriteLine(d.array.Count);
Wynik:
1000
string
6
Dokumentacja tutaj: LINQ do JSON z Json.NET
Zobacz także JObject.Parse i JArray.Parse
JArray.Parse
.
Dim d As Object = JObject.Parse("{number:1000, str:'string', array: [1,2,3,4,5,6]}")
Począwszy od wersji Json.NET 4.0 wydanie 1, dostępna jest natywna obsługa dynamiczna:
[Test]
public void DynamicDeserialization()
{
dynamic jsonResponse = JsonConvert.DeserializeObject("{\"message\":\"Hi\"}");
jsonResponse.Works = true;
Console.WriteLine(jsonResponse.message); // Hi
Console.WriteLine(jsonResponse.Works); // True
Console.WriteLine(JsonConvert.SerializeObject(jsonResponse)); // {"message":"Hi","Works":true}
Assert.That(jsonResponse, Is.InstanceOf<dynamic>());
Assert.That(jsonResponse, Is.TypeOf<JObject>());
}
I oczywiście najlepszym sposobem na uzyskanie aktualnej wersji jest NuGet.
Zaktualizowano (11.12.2014) w celu uwzględnienia komentarzy:
Działa to doskonale. Jeśli sprawdzisz typ w debuggerze, zobaczysz, że wartość jest w rzeczywistości dynamiczna . Typu bazowego jest JObject
. Jeśli chcesz kontrolować typ (np. Określanie ExpandoObject
, zrób to).
@Model.Prop
nazwy w Razor, jeśli typem zwrotu jest JValue.
JValue
. Co mnie zdezorientowało, ponieważ pracowałem w oknie debuggera / bezpośredniego i nie widziałem tylko string
s. David pokazuje to na dolnym zrzucie ekranu. JValue
Jest wymienialna, dzięki czemu można po prostu zrobićstring m = jsonResponse.message
Jeśli deserializujesz tylko dynamicznie, odzyskasz JObject. Możesz uzyskać to, czego chcesz, korzystając z ExpandoObject.
var converter = new ExpandoObjectConverter();
dynamic message = JsonConvert.DeserializeObject<ExpandoObject>(jsonString, converter);
Wiem, że to stary post, ale JsonConvert ma inną metodę, więc tak by było
var product = new { Name = "", Price = 0 };
var jsonResponse = JsonConvert.DeserializeAnonymousType(json, product);
Tak, możesz to zrobić za pomocą JsonConvert.DeserializeObject. Aby to zrobić, po prostu wykonaj:
dynamic jsonResponse = JsonConvert.DeserializeObject(json);
Console.WriteLine(jsonResponse["message"]);
JsonConvert
nie zawiera metody o nazwie Deserialize
.
Uwaga: w czasie, gdy odpowiedziałem na to pytanie w 2010 r., Nie było sposobu na deserializację bez jakiegoś rodzaju, pozwoliło to na deserializację bez konieczności definiowania rzeczywistej klasy i pozwoliło na użycie anonimowej klasy do przeprowadzenia deserializacji.
Musisz mieć jakiś typ do deserializacji. Możesz zrobić coś w stylu:
var product = new { Name = "", Price = 0 };
dynamic jsonResponse = JsonConvert.Deserialize(json, product.GetType());
Moja odpowiedź oparta jest na rozwiązaniu do .NET 4.0 w wersji serializatora JSON. Link do deserializacji do typów anonimowych znajduje się tutaj:
Jeśli używasz JSON.NET ze starą wersją, która nie JObject.
Jest to kolejny prosty sposób na utworzenie obiektu dynamicznego z JSON: https://github.com/chsword/jdynamic
NuGet Zainstaluj
PM> Install-Package JDynamic
Wsparcie przy użyciu indeksu ciągów, aby uzyskać dostęp do członka, takiego jak:
dynamic json = new JDynamic("{a:{a:1}}");
Assert.AreEqual(1, json["a"]["a"]);
Przypadek testowy
Możesz użyć tego narzędzia w następujący sposób:
Uzyskaj wartość bezpośrednio
dynamic json = new JDynamic("1");
//json.Value
2. Pobierz element członkowski w obiekcie json
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 integer: 1
3.Ilość
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.
Inny
dynamic json = new JDynamic("{a:{a:1} }");
//json.a.a is 1.
Tak to mozliwe. Robiłem to cały czas.
dynamic Obj = JsonConvert.DeserializeObject(<your json string>);
Jest to nieco trudniejsze w przypadku typów innych niż rodzime. Załóżmy, że w twoim Obj znajdują się obiekty ClassA i ClassB. Wszystkie są konwertowane na JObject. Co musisz zrobić, to:
ClassA ObjA = Obj.ObjA.ToObject<ClassA>();
ClassB ObjB = Obj.ObjB.ToObject<ClassB>();