Як я перераховую через JObject?


111

Я намагаюся визначити, як отримати доступ до даних, що знаходяться в моєму JObject, і я не можу все життя визначати, як ним користуватися.

JObject Object = (JObject)Response.Data["my_key"];

Я можу роздрукувати його на консолі, роблячи Console.WriteLine (Object), і я бачу дані, це виглядає так:

{
 "my_data" : "more of my string data"
...
}

Але я не маю ідеї, як просто повторити / перерахувати через це, хтось має ідеї? Я зараз у такій втраті.

Відповіді:


167

Якщо ви подивитеся на документаціюJObject , ви побачите, що вона реалізується IEnumerable<KeyValuePair<string, JToken>>. Отже, ви можете перебрати його просто за допомогою foreach:

foreach (var x in obj)
{
    string name = x.Key;
    JToken value = x.Value;
    
}

3
Це правильно, але з моїх причин я не розумію, ви не можете використовувати його з Linq, якщо ви прямо не переймете до переліченого типу. Тобто ти ((IEnumerable<KeyValuePair<string, JToken>>)obj).Select(...)замість простого старого obj.Select(...); або, принаймні, це те, що я знайшов це частиною мого коду.
Адріан Ратнапала

2
@AdrianRatnapala Чи є ваш obj оголошений динамічним? Методи розширення (наприклад, Enumerable.Select) не працюють з цим.
svick

1
Ні, в моєму випадку objмав тип JObject; але, JObjectсхоже, мають подібні проблеми dynamic. Компілятор не може зробити аргументи типу для .Select. Я можу їх чітко дати, obj.Select<KeyValuePair<string, JToken>, (result type)>(...)також працює для мене
Адріан Ратнапала

3
@AdrianRatnapala Хм, ти маєш рацію. Це тому, що JObjectреалізує як IEnumerable<KeyValuePair<string, JToken>>і IEnumerable<JToken>(опосередковано через JContainer).
svick

3
Тепер як я можу використовувати його для вкладеного JSON? Наприклад, якщо "значення" містить інший набір ключів: пари значень, як я можу використовувати JToken valueітерацію через наступний набір пар?
AlbatrossCafe

53

JObjects можна перерахувати через об’єкти JProperty , відкинувши їх до JToken :

foreach (JProperty x in (JToken)obj) { // if 'obj' is a JObject
    string name = x.Name;
    JToken value = x.Value;
}

Якщо у вас вкладений JObject всередині іншого JObject, вам не потрібно робити трансляцію, оскільки аксесуар поверне JToken:

foreach (JProperty x in obj["otherObject"]) { // Where 'obj' and 'obj["otherObject"]' are both JObjects
    string name = x.Name;
    JToken value = x.Value;
}

3
Ви можете також зручно використовувати LINQ наступним чином: obj.Properties().Select(p => p.Name + ": " + p.Value).
itslittlejohn

Це була саме така інформація, яку я шукав. Дуже дякую!
jhoepken

15

Відповідь для мене не спрацювала. Я не знаю, як набралося стільки голосів. Хоча це допомагало вказувати мені в бік.

Це відповідь, яка працювала на мене:

foreach (var x in jobj)
{
    var key = ((JProperty) (x)).Name;
    var jvalue = ((JProperty)(x)).Value ;
}

1
З цим (після цього рядка: JObject priceComplianceJson = JObject.Parse (File.ReadAllText (fullPath));) я отримую "Неможливо перетворити тип" System.Collections.Generic.KeyValuePair <string, Newtonsoft.Json.Linq.JToken> ' до 'Newtonsoft.Json.Linq.JProperty' "Видалення робіт кастингу, хоча: var key = x.Key; var jvalue = x.Value; - принаймні, це компілюється ... Завтра я буду функціонувати.
Б. Клей Шеннон

3

Для таких людей, як я, наркомани , і на основі відповіді Svick , ось підхід linq:

using System.Linq;
//...
//make it linq iterable. 
var obj_linq = Response.Cast<KeyValuePair<string, JToken>>();

Тепер ви можете робити вирази linq на зразок:

JToken x = obj_linq
          .Where( d => d.Key == "my_key")
          .Select(v => v)
          .FirstOrDefault()
          .Value;
string y = ((JValue)x).Value;

Або просто:

var y = obj_linq
       .Where(d => d.Key == "my_key")
       .Select(v => ((JValue)v.Value).Value)
       .FirstOrDefault();

Або це повторити всі дані:

obj_linq.ToList().ForEach( x => { do stuff } ); 
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.