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?

200   2  

2 ответов:

JContainer является базовым классом для элементов JSON, имеющих дочерние элементы. JObject, JArray, JProperty и все наследуют от него.

Например, следующий код:

(JObject)JsonConvert.DeserializeObject("[1, 2, 3]")

Бросит InvalidCastException, но если вы бросите его в JContainer, это будет нормально.

Что касается вашего первоначального вопроса, если вы знаете, что у вас есть объект JSON на верхнем уровне, вы можете просто использовать:
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 JObject is a JContainer, который является a JToken.

Вот основное эмпирическое правило:
  • Если вы знаете, что у вас есть объект (обозначенный фигурными скобками { и } в JSON), использовать JObject
  • Если вы знаете, что у вас есть массив или список (обозначенный квадратными скобками [ и ]), используйте JArray
  • Если вы знаете, что у вас есть примитивное значение, используйте JValue
  • Если вы не знаете, какой маркер у вас есть, или хотите иметь возможность обрабатывать любой из вышеперечисленных в общем виде, используйте JToken. Затем вы можете проверить его свойство Type, чтобы определить, что это за маркер, и привести его соответствующим образом.
    Ничего не найдено.

Добавить ответ:
Отменить.