Click or drag to resize
Json.NET

Querying JSON with LINQ

 

LINQ to JSON provides a number of methods for getting data from its objects. The index methods on JObject/JArray let you quickly get data by its property name on an object or index in a collection, while Children lets you get ranges of data as IEnumerable<JToken> to then query using LINQ.

Getting values by Property Name or Collection Index

The simplest way to get a value from LINQ to JSON is to use the ItemObject index on JObject/JArray and then cast the returned JValue to the type you want.

Getting JSON Values
string json = @"{
  'channel': {
    'title': 'James Newton-King',
    'link': 'http://james.newtonking.com',
    'description': 'James Newton-King\'s blog.',
    'item': [
      {
        'title': 'Json.NET 1.3 + New license + Now on CodePlex',
        'description': 'Annoucing the release of Json.NET 1.3, the MIT license and the source on CodePlex',
        'link': 'http://james.newtonking.com/projects/json-net.aspx',
        'categories': [
          'Json.NET',
          'CodePlex'
        ]
      },
      {
        'title': 'LINQ to JSON beta',
        'description': 'Annoucing LINQ to JSON',
        'link': 'http://james.newtonking.com/projects/json-net.aspx',
        'categories': [
          'Json.NET',
          'LINQ'
        ]
      }
    ]
  }
}";

JObject rss = JObject.Parse(json);

string rssTitle = (string)rss["channel"]["title"];
// James Newton-King

string itemTitle = (string)rss["channel"]["item"][0]["title"];
// Json.NET 1.3 + New license + Now on CodePlex

JArray categories = (JArray)rss["channel"]["item"][0]["categories"];
// ["Json.NET", "CodePlex"]

IList<string> categoriesText = categories.Select(c => (string)c).ToList();
// Json.NET
// CodePlex
Querying with LINQ

JObject/JArray can also be queried using LINQ. Children returns the children values of a JObject/JArray as an IEnumerable<JToken> that can then be queried with the standard Where/OrderBy/Select LINQ operators.

Note Note

Children returns all the children of a token. If it is a JObject it will return a collection of properties to work with, and if it is a JArray you will get a collection of the array's values.

Querying JSON
var postTitles =
    from p in rss["channel"]["item"]
    select (string)p["title"];

foreach (var item in postTitles)
{
    Console.WriteLine(item);
}

//LINQ to JSON beta
//Json.NET 1.3 + New license + Now on CodePlex

var categories =
    from c in rss["channel"]["item"].SelectMany(i => i["categories"]).Values<string>()
    group c by c
    into g
    orderby g.Count() descending
    select new { Category = g.Key, Count = g.Count() };

foreach (var c in categories)
{
    Console.WriteLine(c.Category + " - Count: " + c.Count);
}

//Json.NET - Count: 2
//LINQ - Count: 1
//CodePlex - Count: 1

LINQ to JSON can also be used to manually convert JSON to a .NET object.

Deserializing Using LINQ Objects
public class Shortie
{
    public string Original { get; set; }
    public string Shortened { get; set; }
    public string Short { get; set; }
    public ShortieException Error { get; set; }
}

public class ShortieException
{
    public int Code { get; set; }
    public string ErrorMessage { get; set; }
}

Manually serializing and deserializing between .NET objects is useful when you are working with JSON that doesn't closely match your .NET objects.

Deserializing Using LINQ Example
string jsonText = @"{
  'short': {
    'original': 'http://www.foo.com/',
    'short': 'krehqk',
    'error': {
      'code': 0,
      'msg': 'No action taken'
    }
  }
}";

JObject json = JObject.Parse(jsonText);

Shortie shortie = new Shortie
{
    Original = (string)json["short"]["original"],
    Short = (string)json["short"]["short"],
    Error = new ShortieException
    {
        Code = (int)json["short"]["error"]["code"],
        ErrorMessage = (string)json["short"]["error"]["msg"]
    }
};

Console.WriteLine(shortie.Original);
// http://www.foo.com/

Console.WriteLine(shortie.Error.ErrorMessage);
// No action taken
See Also