Come faccio a enumerare tramite un JObject?


111

Sto cercando di determinare come accedere ai dati che si trovano nel mio JObject e non posso per la vita di determinare come usarli.

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

Posso stamparlo sulla console facendo Console.WriteLine (Object) e vedo i dati, sembra:

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

Ma non ho idea di come iterare / enumerare solo attraverso di esso, qualcuno ha qualche idea? Sono così in perdita adesso.

Risposte:


167

Se guardi la documentazione perJObject , vedrai che implementa IEnumerable<KeyValuePair<string, JToken>>. Quindi, puoi iterare su di esso semplicemente usando un foreach:

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

3
Questo è corretto, ma per motivi che non capisco, non puoi usarlo con Linq a meno che non esegui il cast esplicito al tipo enumerabile. Cioè tu ((IEnumerable<KeyValuePair<string, JToken>>)obj).Select(...)invece che semplice vecchio obj.Select(...); o almeno questo è quello che ho trovato una parte del mio codice.
Adrian Ratnapala

2
@AdrianRatnapala Il tuo oggetto è dichiarato dinamico? I metodi di estensione (come Enumerable.Select) non funzionano con quello.
svick

1
No, nel mio caso objaveva il tipo JObject; ma JObjectsembra avere problemi simili a dynamic. Il compilatore non può dedurre gli argomenti di tipo a .Select. Posso darli esplicitamente, obj.Select<KeyValuePair<string, JToken>, (result type)>(...)funziona anche per me
Adrian Ratnapala

3
@AdrianRatnapala Hmm, hai ragione. È perché JObjectimplementa sia IEnumerable<KeyValuePair<string, JToken>>e IEnumerable<JToken>(indirettamente tramite JContainer).
svick

3
Ora come lo uso per JSON nidificato? Ad esempio, se il "valore" contiene un altro insieme di coppie chiave: valore, come posso utilizzare il JToken valueper scorrere il prossimo insieme di coppie?
AlbatrossCafe

53

Gli oggetti JO possono essere enumerati tramite oggetti JProperty eseguendo il cast a un JToken :

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

Se hai un JObject annidato all'interno di un altro JObject, non è necessario eseguire il cast perché la funzione di accesso restituirà un JToken:

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

3
È possibile anche comodamente usare LINQ in questo modo: obj.Properties().Select(p => p.Name + ": " + p.Value).
itslittlejohn

Questa era esattamente l'informazione che stavo cercando. Grazie mille!
jhoepken

15

La risposta non ha funzionato per me. Non so come abbia ottenuto così tanti voti. Anche se mi ha aiutato a indicarmi una direzione.

Questa è la risposta che ha funzionato per me:

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

1
Con questo (dopo questa riga: JObject priceComplianceJson = JObject.Parse (File.ReadAllText (fullPath));) ottengo, "Impossibile convertire il tipo 'System.Collections.Generic.KeyValuePair <string, Newtonsoft.Json.Linq.JToken>' a 'Newtonsoft.Json.Linq.JProperty' "La rimozione del casting funziona, però: var key = x.Key; var jvalue = x.Value; - almeno si compila ... domani ceco la funzionalità.
B. Clay Shannon

3

Per persone come me, dipendenti da linq e in base alla risposta di svick , ecco un approccio linq:

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

Ora puoi creare espressioni linq come:

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

O semplicemente:

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

O questo per iterare su tutti i dati:

obj_linq.ToList().ForEach( x => { do stuff } ); 
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.