it-swarm.com.ru

Десериализовать объект json в динамический объект с помощью Json.net

Можно ли вернуть динамический объект из десериализации json, используя json.net? Я хотел бы сделать что-то вроде этого:

dynamic jsonResponse = JsonConvert.Deserialize(json);
Console.WriteLine(jsonResponse.message);
374
ryudice

последняя версия json.net позволяет сделать это:

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

Результат:

 1000
 string
 6

Документация здесь: LINQ to JSON с Json.NET

483
Michael Pakhantsov

Начиная с Json.NET 4.0 Release 1 имеется встроенная динамическая поддержка:

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

И, конечно же, лучший способ получить текущую версию - через NuGet.

Обновлено (12/12/2014) с учетом комментариев:

Это прекрасно работает. Если вы проверите тип в отладчике, вы увидите, что значение на самом деле dynamic. Базовый тип является JObject. Если вы хотите контролировать тип (например, указав ExpandoObject, сделайте это).

enter image description here

97
David Peden

Если вы просто десериализуетесь в динамический, вы получите JObject обратно. Вы можете получить то, что вы хотите, используя ExpandoObject.

var converter = new ExpandoObjectConverter();    
dynamic message = JsonConvert.DeserializeObject<ExpandoObject>(jsonString, converter);
47
Joshua Peterson

Я знаю, что это старый пост, но JsonConvert на самом деле имеет другой метод, поэтому было бы

var product = new { Name = "", Price = 0 };
var jsonResponse = JsonConvert.DeserializeAnonymousType(json, product);
37
epitka

Да, вы можете сделать это с помощью JsonConvert.DeserializeObject. Для этого достаточно просто сделать:

dynamic jsonResponse = JsonConvert.DeserializeObject(json);
Console.WriteLine(jsonResponse["message"]);
20
oteal

Примечание: В то время, когда я отвечал на этот вопрос в 2010 году, не было никакого способа десериализации без какого-либо типа, это позволило вам десериализовать без необходимости определять фактический класс и позволяло использовать анонимный класс для выполнения десериализация. 


Вам нужно иметь какой-то тип для десериализации. Вы могли бы сделать что-то вроде:

var product = new { Name = "", Price = 0 };
dynamic jsonResponse = JsonConvert.Deserialize(json, product.GetType());

Мой ответ основан на решении для сборки .NET 4.0 в сериализаторе JSON. Ссылка для десериализации на анонимные типы находится здесь:

http://blogs.msdn.com/b/alexghi/archive/2008/12/22/using-anonymous-types-to-deserialize-json-data.aspx

18
Phill

Если вы используете JSON.NET со старой версией, которая не JObject.

Это еще один простой способ сделать динамический объект из JSON: https://github.com/chsword/jdynamic

NuGet Установить

PM> Install-Package JDynamic

Поддержка использования строкового индекса для доступа к члену, как:

dynamic json = new JDynamic("{a:{a:1}}");
Assert.AreEqual(1, json["a"]["a"]);

Прецедент

И вы можете использовать эту утилиту следующим образом:

Получить значение напрямую

dynamic json = new JDynamic("1");

//json.Value

2. Получить член в объекте 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.IEnumerable

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.

Другой

dynamic json = new JDynamic("{a:{a:1} }");

//json.a.a is 1.
5
chsword

Да, это возможно. Я делал это все время.

dynamic Obj = JsonConvert.DeserializeObject(<your json string>);

Это немного сложнее для неродного типа. Предположим, внутри вашего объекта Obj есть объекты ClassA и ClassB. Все они конвертированы в JObject. Что вам нужно сделать, это:

ClassA ObjA = Obj.ObjA.ToObject<ClassA>();
ClassB ObjB = Obj.ObjB.ToObject<ClassB>();
0
s k