Jcontainer, JObject, JToken и Linq путаница
Мне трудно понять, когда использовать JContainer, JObject, и JToken. Я понимаю из "стандартов", что JObject состоит из JProperties и что JToken является базовым абстрактным классом для всех типов JToken, но я не понимаю JContainer.
Я использую C# и только что купил LinqPad Pro 5.
У меня есть источник данных JSON в файле, поэтому я успешно десериализую содержимое этого файла с помощью этого оператора:
string json;
using (StreamReader reader = new StreamReader(@"myjsonfile.json"))
{
json = reader.ReadToEnd();
}
В этот момент я беру строку JSON объект и десериализовать его в JObject (и это может быть моей ошибкой-возможно, мне нужно сделать jsonWork A JToken или JContainer?):
JObject jsonWork = (JObject)JsonConvert.DeserializeObject(json);
В моих данных JSON (строка, представленная JSON), у меня есть три объекта-объект верхнего уровня выглядит примерно так:
{
"Object1" : { ... },
"Object2" : { ... },
"Object3" : { ... }
}
Каждый объект состоит из всевозможных маркеров (массивов, строк, других объектов и т. д.).), так что это динамический JSON. (Я использовал эллипсы в качестве заполнителей вместо того, чтобы запутывать этот вопрос с большим количеством данных JSON.)
Я хочу обрабатывать "Object1", "Object2", и "Object3" отдельно используя LINQ, однако. Поэтому, в идеале, я хотел бы что-то вроде этого:
// these lines DO NOT work
var jsonObject1 = jsonWork.Children()["Object1"]
var jsonObject2 = jsonWork.Children()["Object2"]
var jsonObject3 = jsonWork.Children()["Object3"]
Но вышеприведенные строки терпят неудачу.
Я использовал var выше, потому что я понятия не имею, какой тип объекта я должен использовать: JContainer, JObject, или JToken! Просто чтобы вы знали, что я хочу сделать, как только вышеупомянутые переменные jsonObject# будут правильно назначены, я хотел бы использовать LINQ для запроса JSON, который они содержат. Вот очень простой пример:
var query = from p in jsonObject1
where p.Name == "Name1"
select p
Конечно, мой LINQ в конечном итоге будут фильтроваться массивы JSON, объекты, строки и т. д., в переменной jsonObject. Я думаю, что как только я начну, я смогу использовать LinqPad, чтобы помочь мне фильтровать JSON с помощью LINQ.
Я обнаружил, что если я использую:
// this line WORKS
var jsonObject1 = ((JObject)jsonWork).["Object1"];
Затем я получаю JObject тип в jsonObject1. Является ли это правильным подходом?
Мне непонятно, когда/зачем использовать JContainer, Когда кажется, что JToken и JObject объекты работают с LINQ довольно хорошо. Какова цель JContainer?
2 ответов:
JContainerявляется базовым классом для элементов JSON, имеющих дочерние элементы.JObject,JArray,JPropertyи все наследуют от него.Например, следующий код:
(JObject)JsonConvert.DeserializeObject("[1, 2, 3]")Бросит
Что касается вашего первоначального вопроса, если вы знаете, что у вас есть объект JSON на верхнем уровне, вы можете просто использовать:InvalidCastException, но если вы бросите его вJContainer, это будет нормально.var jsonWork = JObject.Parse(json); var jsonObject1 = o["Object1"];
В большинстве случаев вам действительно не нужно беспокоиться о
JContainer. Он помогает организовать и структурировать LINQ-to-JSON в хорошо продуманный код.
JTokenиерархия выглядит так: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)Итак, вы видите, a
Вот основное эмпирическое правило:JObjectis aJContainer, который является aJToken.
- Если вы знаете, что у вас есть объект (обозначенный фигурными скобками
{и}в JSON), использоватьJObject- Если вы знаете, что у вас есть массив или список (обозначенный квадратными скобками
[и]), используйтеJArray- Если вы знаете, что у вас есть примитивное значение, используйте
JValue- Если вы не знаете, какой маркер у вас есть, или хотите иметь возможность обрабатывать любой из вышеперечисленных в общем виде, используйте
JToken. Затем вы можете проверить его свойствоType, чтобы определить, что это за маркер, и привести его соответствующим образом.
Comments