web-dev-qa-db-fra.com

Désérialiser un objet json en objet dynamique à l'aide de Json.net

Est-il possible de renvoyer un objet dynamique à partir d'une désérialisation json à l'aide de json.net? J'aimerais faire quelque chose comme ça:

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

la dernière version de json.net permet de faire ceci:

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

sortie:

 1000
 string
 6

Documentation ici: LINQ to JSON avec Json.NET

483
Michael Pakhantsov

A partir de Json.NET 4.0 Release 1, il existe un support dynamique natif:

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

Et, bien sûr, le meilleur moyen d’obtenir la version actuelle est via NuGet.

Mis à jour (11/12/2014) pour répondre aux commentaires:

Cela fonctionne parfaitement bien. Si vous inspectez le type dans le débogueur, vous verrez que la valeur est, en fait, dynamic. Le type sous-jacent est une JObject. Si vous souhaitez contrôler le type (par exemple, en spécifiant ExpandoObject, faites-le.

enter image description here

97
David Peden

Si vous ne désérialisez que dynamique, vous obtiendrez un objet de retour. Vous pouvez obtenir ce que vous voulez en utilisant un ExpandoObject.

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

Je sais que c'est vieux post, mais JsonConvert a en fait une méthode différente de sorte qu'il serait

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

Oui, vous pouvez le faire en utilisant JsonConvert.DeserializeObject. Pour faire cela, faites simplement:

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

Note: À l'époque où j'ai répondu à cette question en 2010, il n'y avait aucun moyen de désérialiser sans une sorte de type, cela vous permettait de désérialiser sans avoir à définir la classe réelle et de permettre l'utilisation d'une classe anonyme. la désérialisation. 


Vous devez avoir une sorte de type pour désérialiser. Vous pouvez faire quelque chose comme:

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

Ma réponse est basée sur une solution pour le sérialiseur JSON intégré à .NET 4.0. Le lien pour désérialiser les types anonymes est ici:

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

18
Phill

Si vous utilisez JSON.NET avec une ancienne version qui ne contenait pas JObject.

Voici un autre moyen simple de créer un objet dynamique à partir de JSON: https://github.com/chsword/jdynamic

NuGet Installer

PM> Install-Package JDynamic

Prise en charge de l'utilisation de l'index de la chaîne pour accéder aux membres, comme

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

Cas de test

Et vous pouvez utiliser cet util comme suit:

Obtenez la valeur directement

dynamic json = new JDynamic("1");

//json.Value

2.Obtenez le membre dans l'objet 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.Innombrable

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.

Autre

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

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

Oui c'est possible. Je le fais depuis le début.

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

C'est un peu plus compliqué pour le type non natif. Supposons que dans votre Obj, il y a un objet ClassA et des objets ClassB. Ils sont tous convertis en JObject. Ce que vous devez faire c'est:

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