145

I'm trying to determine how to access the data that is in my JObject and I can't for the life of me determine how to use it.

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

I can print it to the console doing Console.WriteLine(Object) and I see the data, it looks like:

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

But I have NO idea how to just iterate/enumerate through it, anyone have any ideas? I'm at such a loss right now.

svick
  • 236,525
  • 50
  • 385
  • 514
Geesu
  • 5,928
  • 11
  • 43
  • 72

4 Answers4

221

If you look at the documentation for JObject, you will see that it implements IEnumerable<KeyValuePair<string, JToken>>. So, you can iterate over it simply using a foreach:

foreach (var x in obj)
{
    string name = x.Key;
    JToken value = x.Value;
    …
}
svick
  • 236,525
  • 50
  • 385
  • 514
  • 3
    This is correct, but for reasons I don't understand, you can't use it with Linq unless you explicitly cast to the enumerable type. I.e. you `((IEnumerable>)obj).Select(...)` instead of plain-old `obj.Select(...)`; or at least that's what I found it one part of my code. – Adrian Ratnapala Nov 26 '14 at 09:26
  • 2
    @AdrianRatnapala Is your obj declared dynamic? Extension methods (like Enumerable.Select) don't work with that. – svick Nov 26 '14 at 19:36
  • 1
    No, in my case `obj` had type `JObject`; but `JObject` seems to have similar problems to `dynamic`. The compiler can't infer the type arguments to `.Select`. I can give them explictly, `obj.Select, (result type)>(...)` also works for me – Adrian Ratnapala Nov 27 '14 at 05:11
  • 3
    @AdrianRatnapala Hmm, you're right. It's because `JObject` implements both `IEnumerable>` and `IEnumerable` (indirectly through `JContainer`). – svick Nov 29 '14 at 15:12
  • 3
    Now how do I use it for nested JSON? For example, if the "value" contains another set of key:value pairs, how can I use the `JToken value` to iterate through next set of pairs? – AlbatrossCafe Aug 14 '15 at 22:52
  • 2
    @AdrianRatnapala Try using the `Properties()` method on `JObject`. For example: `jObject.Properties().Select(p => p.Name + ": " + p.Value)`. – itslittlejohn Aug 02 '17 at 15:06
67

JObjects can be enumerated via JProperty objects by casting it to a JToken:

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

If you have a nested JObject inside of another JObject, you don't need to cast because the accessor will return a JToken:

foreach (JProperty x in obj["otherObject"]) { // Where 'obj' and 'obj["otherObject"]' are both JObjects
    string name = x.Name;
    JToken value = x.Value;
}
Daniel
  • 8,655
  • 5
  • 60
  • 87
20

The answer did not work for me. I dont know how it got so many votes. Though it helped in pointing me in a direction.

This is the answer that worked for me:

foreach (var x in jobj)
{
    var key = ((JProperty) (x)).Name;
    var jvalue = ((JProperty)(x)).Value ;
}
B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862
jaxxbo
  • 7,314
  • 4
  • 35
  • 48
  • 1
    With that (after this line: JObject priceComplianceJson = JObject.Parse(File.ReadAllText(fullPath));) I get, "Cannot convert type 'System.Collections.Generic.KeyValuePair' to 'Newtonsoft.Json.Linq.JProperty'" Removing the casting works, though: var key = x.Key; var jvalue = x.Value; - at least it compiles...I'll czech the functionality tomorrow. – B. Clay Shannon-B. Crow Raven Dec 31 '15 at 00:29
6

For people like me, linq addicts, and based on svick's answer, here a linq approach:

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

Now you can make linq expressions like:

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

Or just:

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

Or this one to iterate over all data:

obj_linq.ToList().ForEach( x => { do stuff } ); 
dani herrera
  • 48,760
  • 8
  • 117
  • 177