Bir JObject aracılığıyla nasıl numaralandırırım?


111

JObject'imdeki verilere nasıl erişeceğimi belirlemeye çalışıyorum ve onu nasıl kullanacağımı ömür boyu belirleyemiyorum.

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

Console.WriteLine (Object) yaparak bunu konsola yazdırabilirim ve verileri görüyorum, şöyle görünüyor:

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

Ama bunu nasıl tekrarlayacağım / sıralayacağım hakkında HİÇBİR fikrim yok, herhangi bir fikri olan var mı? Şu anda büyük bir kaybım var.

Yanıtlar:


167

BelgelerineJObject bakarsanız, uyguladığını göreceksiniz IEnumerable<KeyValuePair<string, JToken>>. Yani, basitçe a kullanarak yineleyebilirsiniz foreach:

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

3
Bu doğru, ancak anlayamadığım nedenlerden dolayı, numaralandırılabilir türe açıkça atmadıkça Linq ile kullanamazsınız. ((IEnumerable<KeyValuePair<string, JToken>>)obj).Select(...)Sade-eski yerine sen obj.Select(...); ya da en azından bunu kodumun bir parçası olarak buldum.
Adrian Ratnapala

2
@AdrianRatnapala objeniz dinamik mi ilan edildi? Uzantı yöntemleri (Enumerable.Select gibi) bununla çalışmaz.
svick

1
Hayır, benim durumumda objtip vardı JObject; ama JObjectbenzer sorunları var gibi görünüyor dynamic. Derleyici, tür bağımsız değişkenlerini çıkaramaz .Select. Onları açık bir şekilde verebilirim, obj.Select<KeyValuePair<string, JToken>, (result type)>(...)benim için de işe
yarar

3
@AdrianRatnapala Hmm, haklısın. Çünkü JObjecthem IEnumerable<KeyValuePair<string, JToken>>ve IEnumerable<JToken>(dolaylı olarak JContainer) uygular .
svick

3
Şimdi bunu iç içe geçmiş JSON için nasıl kullanırım? Örneğin, "değer" başka bir anahtar: değer çifti kümesi içeriyorsa, JToken valuesonraki çiftler kümesini yinelemek için nasıl kullanabilirim ?
AlbatrossCafe

53

JObjects aracılığıyla sıralanabilir JProperty bir o döküm yoluyla nesneler JToken :

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

Başka bir JObject'in içinde yuvalanmış bir JObject'e sahipseniz, döküm yapmanıza gerek yoktur çünkü erişimci bir JToken döndürecektir:

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

3
Ayrıca elverişli şöyle linq kullanabilirsiniz: obj.Properties().Select(p => p.Name + ": " + p.Value).
itslittlejohn

Bu tam olarak aradığım bilgiydi. Çok teşekkür ederim!
jhoepken

15

Cevap benim için işe yaramadı. Nasıl bu kadar çok oy aldığını bilmiyorum. Beni bir yöne yönlendirmeme yardımcı oldu.

Benim için işe yarayan cevap bu:

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

1
Bununla (bu satırdan sonra: JObject priceComplianceJson = JObject.Parse (File.ReadAllText (fullPath));) "System.Collections.Generic.KeyValuePair türü dönüştürülemiyor <string, Newtonsoft.Json.Linq.JToken> ' 'Newtonsoft.Json.Linq.JProperty' "Döküm çalışmalarını kaldırma, ancak: var key = x.Key; var jvalue = x.Value; - en azından derler ... İşlevselliği yarın çekeceğim.
B. Clay Shannon

3

Benim gibi insanlar için, linq bağımlıları ve svick'in cevabına göre , işte bir linq yaklaşımı:

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

Şimdi aşağıdaki gibi linq ifadeleri yapabilirsiniz:

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

Ya da sadece:

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

Veya bu, tüm verileri yinelemek için:

obj_linq.ToList().ForEach( x => { do stuff } ); 
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.