Bagaimana cara menghitung melalui JObject?

111

Saya mencoba menentukan cara mengakses data yang ada di JObject saya dan saya tidak bisa seumur hidup saya menentukan cara menggunakannya.

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

Saya dapat mencetaknya ke konsol dengan melakukan Console.WriteLine (Object) dan saya melihat datanya, terlihat seperti:

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

Tapi saya TIDAK tahu bagaimana cara mengulang / menghitungnya, ada yang punya ide? Saya bingung sekarang.

Geesu
sumber

Jawaban:

167

Jika Anda melihat dokumentasinyaJObject , Anda akan melihat bahwa dokumentasinya diimplementasikan IEnumerable<KeyValuePair<string, JToken>>. Jadi, Anda dapat mengulanginya hanya dengan menggunakan foreach:

foreach (var x in obj)
{
    string name = x.Key;
    JToken value = x.Value;
    
}
svick.dll
sumber
3
Ini benar, tetapi untuk alasan yang saya tidak mengerti, Anda tidak dapat menggunakannya dengan Linq kecuali Anda secara eksplisit memasukkan ke tipe enumerable. Yaitu Anda ((IEnumerable<KeyValuePair<string, JToken>>)obj).Select(...)bukan polos-tua obj.Select(...); atau setidaknya itulah yang saya temukan sebagai salah satu bagian dari kode saya.
Adrian Ratnapala
2
@AdrianRatnapala Apakah obj Anda dinyatakan dinamis? Metode ekstensi (seperti Enumerable.Select) tidak berfungsi dengan itu.
svick
1
Tidak, dalam kasus saya objmemiliki tipe JObject; tetapi JObjecttampaknya memiliki masalah yang mirip dengan dynamic. Kompilator tidak dapat menyimpulkan argumen type ke .Select. Saya dapat memberikannya secara eksplisit, obj.Select<KeyValuePair<string, JToken>, (result type)>(...)juga bekerja untuk saya
Adrian Ratnapala
3
@AdrianRatnapala Hmm, kamu benar. Itu karena JObjectmengimplementasikan keduanya IEnumerable<KeyValuePair<string, JToken>>dan IEnumerable<JToken>(secara tidak langsung melalui JContainer).
svick
3
Sekarang bagaimana cara menggunakannya untuk JSON bersarang? Misalnya, jika "nilai" berisi kumpulan pasangan kunci: nilai lainnya, bagaimana cara menggunakan the JToken valueuntuk mengulang melalui kumpulan pasangan berikutnya?
AlbatrossCafe
53

JObjects dapat dihitung melalui objek JProperty dengan mentransmisikannya ke JToken :

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

Jika Anda memiliki JObject bersarang di dalam JObject lain, Anda tidak perlu melakukan transmisi karena pengakses akan mengembalikan JToken:

foreach (JProperty x in obj["otherObject"]) { // Where 'obj' and 'obj["otherObject"]' are both JObjects
    string name = x.Name;
    JToken value = x.Value;
}
Daniel
sumber
3
Anda juga dapat mudah menggunakan LINQ seperti: obj.Properties().Select(p => p.Name + ": " + p.Value).
itslittlejohn
Inilah informasi yang saya cari. Terima kasih banyak!
jhoepken
15

Jawabannya tidak berhasil untuk saya. Saya tidak tahu bagaimana itu mendapat begitu banyak suara. Meskipun itu membantu mengarahkan saya ke suatu arah.

Ini adalah jawaban yang berhasil untuk saya:

foreach (var x in jobj)
{
    var key = ((JProperty) (x)).Name;
    var jvalue = ((JProperty)(x)).Value ;
}
jaxxbo.dll
sumber
1
Dengan itu (setelah baris ini: JObject priceComplianceJson = JObject.Parse (File.ReadAllText (fullPath));) saya mendapatkan, "Tidak dapat mengonversi jenis 'System.Collections.Generic.KeyValuePair <string, Newtonsoft.Json.Linq.JToken>' to 'Newtonsoft.Json.Linq.JProperty' "Meskipun demikian, menghapus casting dapat dilakukan: var key = x.Key; var jvalue = x.Value; - setidaknya itu mengkompilasi ... aku akan memeriksa fungsinya besok.
B. Clay Shannon
3

Bagi orang-orang seperti saya, pecandu linq , dan berdasarkan jawaban svick , berikut pendekatan linq:

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

Sekarang Anda dapat membuat ekspresi linq seperti:

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

Atau hanya:

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

Atau yang ini untuk mengulang semua data:

obj_linq.ToList().ForEach( x => { do stuff } ); 
dani herrera
sumber