Comment proposez-vous à stackOverflow de fermer une question comme "trop ancienne"? Cela fait six ans, il y a des réponses valides et des suggestions raisonnables pour chaque version de .net depuis lors ... tellement qu'elles ne sont plus vraiment utiles.
andrew lorien
Réponses:
547
Json.NET nous 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);
Notez que pour les tableaux, la syntaxe est JArray.Parse.
jgillich
4
Pourquoi devons-nous utiliser un mot dynamique? j'ai peur jamais utilisé auparavant: D
MonsterMMORPG
3
Dans VB.Net, vous devez faireDim d As Object = JObject.Parse("{number:1000, str:'string', array: [1,2,3,4,5,6]}")
ilans
2
@MonsterMMORPG Vous devriez être :) Dynamic est un anti pattern dans presque toutes les circonstances, mais, de temps en temps, vous pouvez avoir une situation où il est raisonnable de l'utiliser.
Pluc
4
Avec Newtonsoft.Json 8.0.3 (.NET 4.5.2): Microsoft.CSharp.RuntimeBinder.RuntimeBinderException s'est produite HResult = -2146233088 Message = 'Newtonsoft.Json.Linq.JObject' ne contient pas de définition pour 'nombre' Source = Microsoft .CSharp StackTrace: sur Microsoft.CSharp.RuntimeBinder.RuntimeBinderController.SubmitError (CError pError)
user4698855
107
Depuis Json.NET 4.0 Release 1, il existe une prise en charge dynamique native:
Et, bien sûr, la meilleure façon 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, dynamique . Le type sous-jacent est a JObject. Si vous souhaitez contrôler le type (comme spécifier ExpandoObject, faites-le.
Cela ne semble jamais fonctionner. Il ne renvoie qu'un JObject, pas une variable dynamique.
Paul
12
BTW, cela fonctionne: JsonConvert.DeserializeObject <ExpandoObject> (STRING); avec une désérialisation appropriée, nous n'avons donc pas JObject etc.
Gutek
2
@Gutek ne sais pas quel est votre problème. Avez-vous exécuté le code? J'ai ajouté des assertions au test et ajouté une propriété qui ne se trouve pas dans le json d'origine. Capture d'écran du débogueur incluse.
David Peden
1
@DavidPeden si vous avez JObject et que vous essayez de le lier dans Razor, vous obtiendrez des exceptions. La question portait sur la désérialisation en objet dynamique - JObject est dynamique mais contient des types "propres" comme JValue et non des types primitifs. Je ne peux pas utiliser de @Model.Propnom dans Razor si le type de retour est JValue.
Gutek
2
Cela fonctionne, mais chaque propriété dynamique est un JValue. Ce qui m'a dérouté parce que je travaillais dans le débogueur / fenêtre immédiate et que je ne voyais pas seulement l' stringart. David le montre dans la capture d'écran du bas. Le JValueest convertible pour que vous puissiez le fairestring m = jsonResponse.message
Luke Puplett
66
Si vous venez de désérialiser en dynamique, vous obtiendrez un JObject. Vous pouvez obtenir ce que vous voulez en utilisant un ExpandoObject.
var converter =newExpandoObjectConverter();dynamic message =JsonConvert.DeserializeObject<ExpandoObject>(jsonString, converter);
Ce serait désérialiser une charge utile json en un type anonyme, pas un type dynamique. Les types anonymes et les types dynamiques sont des choses différentes, et je ne pense pas que cela réponde à la question posée.
jrista
1
Faut-il utiliser deux variables? Pourquoi ne pas réutiliser le premier dans la deuxième déclaration?
RenniePet
21
Oui, vous pouvez le faire à l'aide de JsonConvert.DeserializeObject. Pour ce faire, il suffit de faire simplement:
JsonConvertne contient pas de méthode appelée Deserialize.
Can Poyrazoğlu
cela devrait être simplement DeserializeObject, mais cela devrait être la réponse acceptée IMO
superjugy
21
Remarque: Au moment 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 a permis de désérialiser sans avoir à définir la classe réelle et a permis qu'une classe anonyme soit utilisée pour effectuer la désérialisation.
Vous devez avoir une sorte de type à désérialiser. Vous pourriez 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 la construction de .NET 4.0 dans le sérialiseur JSON. Le lien pour désérialiser vers les types anonymes est ici:
Je suis avec toi phill ne sais pas pourquoi les gens votent contre cela, si quelqu'un peut vous plaire, veuillez expliquer pourquoi?
PEO
18
Ils sont downvoting parce que la question concerne la désérialisation sans type.
richard
4
La réponse était valable au moment de sa rédaction en 2010, alors qu'il n'y avait pas d'autre solution. C'était même la réponse acceptée pendant une petite période de temps jusqu'à ce que le support arrive dans JSON.NET.
Phill
1
Cela ne produit pas d'objet dynamique. Cela produit un JObject que vous référencez comme dynamique. Mais c'est toujours un JObject à l'intérieur.
ghostbust555
5
Si vous utilisez JSON.NET avec une ancienne version qui n'a pas JObject.
dynamic json =newJDynamic("{a:'abc'}");//json.a is a string "abc"dynamic json =newJDynamic("{a:3.1416}");//json.a is 3.1416mdynamic json =newJDynamic("{a:1}");//json.a is integer: 1
3.Inombrable
dynamic json =newJDynamic("[1,2,3]");/json.Length/json.Countis3//And you can use json[0]/ json[2] to get the elementsdynamic json =newJDynamic("{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 elementsdynamic json =newJDynamic("[{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 =newJDynamic("{a:{a:1} }");//json.a.a is 1.
C'est un peu plus délicat pour le type non natif. Supposons qu'à l'intérieur de votre Obj, il y ait des objets ClassA et ClassB. Ils sont tous convertis en JObject. Ce que vous devez faire, c'est:
Réponses:
Json.NET nous permet de faire ceci:
Production:
Documentation ici: LINQ to JSON avec Json.NET
Voir aussi JObject.Parse et JArray.Parse
la source
JArray.Parse
.Dim d As Object = JObject.Parse("{number:1000, str:'string', array: [1,2,3,4,5,6]}")
Depuis Json.NET 4.0 Release 1, il existe une prise en charge dynamique native:
Et, bien sûr, la meilleure façon 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, dynamique . Le type sous-jacent est a
JObject
. Si vous souhaitez contrôler le type (comme spécifierExpandoObject
, faites-le.la source
@Model.Prop
nom dans Razor si le type de retour est JValue.JValue
. Ce qui m'a dérouté parce que je travaillais dans le débogueur / fenêtre immédiate et que je ne voyais pas seulement l'string
art. David le montre dans la capture d'écran du bas. LeJValue
est convertible pour que vous puissiez le fairestring m = jsonResponse.message
Si vous venez de désérialiser en dynamique, vous obtiendrez un JObject. Vous pouvez obtenir ce que vous voulez en utilisant un ExpandoObject.
la source
Je sais que c'est un ancien poste, mais JsonConvert a en fait une méthode différente, donc ce serait
la source
Oui, vous pouvez le faire à l'aide de JsonConvert.DeserializeObject. Pour ce faire, il suffit de faire simplement:
la source
JsonConvert
ne contient pas de méthode appeléeDeserialize
.Remarque: Au moment 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 a permis de désérialiser sans avoir à définir la classe réelle et a permis qu'une classe anonyme soit utilisée pour effectuer la désérialisation.
Vous devez avoir une sorte de type à désérialiser. Vous pourriez faire quelque chose comme:
Ma réponse est basée sur une solution pour la construction de .NET 4.0 dans le sérialiseur JSON. Le lien pour désérialiser vers les types anonymes est ici:
http://blogs.msdn.com/b/alexghi/archive/2008/12/22/using-anonymous-types-to-deserialize-json-data.aspx
la source
Si vous utilisez JSON.NET avec une ancienne version qui n'a pas JObject.
C'est une autre façon simple de créer un objet dynamique à partir de JSON: https://github.com/chsword/jdynamic
Installation de NuGet
Prise en charge de l'utilisation de l'index de chaîne pour accéder aux membres comme:
Cas de test
Et vous pouvez utiliser cet util comme suit:
Obtenez la valeur directement
Obtention du membre dans l'objet json
3.Inombrable
Autre
la source
Oui c'est possible. Je le fais depuis toujours.
C'est un peu plus délicat pour le type non natif. Supposons qu'à l'intérieur de votre Obj, il y ait des objets ClassA et ClassB. Ils sont tous convertis en JObject. Ce que vous devez faire, c'est:
la source