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.