J'ai du mal à comprendre quand utiliser JContainer
, JObject
et JToken
. D'après les "normes", je comprends que JObject
est composé de JProperties
et que JToken
est la classe abstraite de base pour tous les types JToken
, mais je ne comprends pas JContainer
.
J'utilise C # et je viens d'acheter LinqPad Pro 5.
J'ai une source de données JSON dans un fichier, je vais donc désérialiser le contenu de ce fichier avec succès en utilisant cette déclaration:
string json;
using (StreamReader reader = new StreamReader(@"myjsonfile.json"))
{
json = reader.ReadToEnd();
}
À ce stade, je prends l’objet chaîne JSON et le désérialise en JObject
(et c’est peut-être mon erreur. Peut-être dois-je créer jsonWork
un JToken
ou JContainer
?):
JObject jsonWork = (JObject)JsonConvert.DeserializeObject(json);
Dans mes données JSON (la chaîne représentée par JSON), j'ai trois objets - l'objet de niveau supérieur ressemble à ceci:
{
"Object1" : { ... },
"Object2" : { ... },
"Object3" : { ... }
}
Chaque objet est composé de toutes sortes de jetons (tableaux, chaînes, autres objets, etc.), il s'agit donc de JSON dynamique. (J'ai utilisé des ellipses comme espaces réservés plutôt que de compliquer la question avec beaucoup de données JSON.)
Je veux traiter "Object1"
, "Object2"
, et "Object3"
séparément à l'aide de LINQ, cependant. Donc, idéalement, j'aimerais quelque chose comme ceci:
// these lines DO NOT work
var jsonObject1 = jsonWork.Children()["Object1"]
var jsonObject2 = jsonWork.Children()["Object2"]
var jsonObject3 = jsonWork.Children()["Object3"]
Mais les lignes ci-dessus échouent.
J'ai utilisé var
ci-dessus parce que je n'ai aucune idée du type d'objet que je devrais utiliser: JContainer
, JObject
ou JToken
! Juste pour que vous sachiez ce que je veux faire, une fois ce qui précède jsonObject#
les variables sont correctement affectées, je voudrais utiliser LINQ pour interroger le JSON qu'elles contiennent. Voici un exemple très simple:
var query = from p in jsonObject1
where p.Name == "Name1"
select p
Bien entendu, mon LINQ finira par filtrer les tableaux, objets, chaînes, etc. JSON, dans la variable jsonObject
. Je pense qu'une fois que j'y vais, je peux utiliser LinqPad pour m'aider à filtrer le JSON à l'aide de LINQ.
J'ai découvert que si j'utilise:
// this line WORKS
var jsonObject1 = ((JObject)jsonWork).["Object1"];
Ensuite, je reçois un JObject
de type jsonObject1
. Est-ce la bonne approche?
Je ne sais pas quand/pourquoi on utiliserait JContainer
alors qu'il semble que les objets JToken
et JObject
fonctionnent assez bien avec LINQ. Quel est le but de JContainer
?
JContainer
est une classe de base pour les éléments JSON ayant des éléments enfants. JObject
, JArray
, JProperty
et JConstructor
en héritent tous.
Par exemple, le code suivant:
(JObject)JsonConvert.DeserializeObject("[1, 2, 3]")
Lancerait un InvalidCastException
, mais si vous le convertissez en un JContainer
, tout irait bien.
En ce qui concerne votre question initiale, si vous savez que vous avez un objet JSON au plus haut niveau, vous pouvez simplement utiliser:
var jsonWork = JObject.Parse(json);
var jsonObject1 = o["Object1"];
Vous n'avez pas vraiment besoin de vous soucier de JContainer
dans la plupart des cas. Il est là pour vous aider à organiser et à structurer LINQ-to-JSON en code bien factorisé.
La hiérarchie JToken
ressemble à ceci:
JToken - abstract base class
JContainer - abstract base class of JTokens that can contain other JTokens
JArray - represents a JSON array (contains an ordered list of JTokens)
JObject - represents a JSON object (contains a collection of JProperties)
JProperty - represents a JSON property (a name/JToken pair inside a JObject)
JValue - represents a primitive JSON value (string, number, boolean, null)
Donc, vous voyez, un JObject
est a JContainer
=, qui est a JToken
.
Voici la règle de base:
{
et }
en JSON), utilisez JObject
[
et ]
), utilisez JArray
JValue
JToken
. Vous pouvez ensuite vérifier sa propriété Type
pour déterminer le type de jeton et le lancer de manière appropriée.