57

This is the JSON I get from a request on .NET:

{
  "id": "110355660738", 
  "picture": {
    "data": {
      "url": "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-prn2/1027085_12033235063_5234302342947_n.jpg", 
      "is_silhouette": false
    }
  }
}

and I'd like to catch the field "url", using (maybe?) LINQ. I do many request as this, that differents a bit. So I won't to create a C# Class and deserialize it every time.

Is it a way to extract a single field? Thank you!

Nikhil Gupta
  • 1,708
  • 1
  • 23
  • 38
markzzz
  • 47,390
  • 120
  • 299
  • 507

4 Answers4

85

No need for Linq, just use dynamic (using Json.Net)

dynamic obj = JObject.Parse(json);
Console.WriteLine((string)obj.picture.data.url);

Linq version would not be much readable

JObject jObj = JObject.Parse(json);
var url = (string)jObj.Descendants()
                    .OfType<JProperty>()
                    .Where(p => p.Name == "url")
                    .First()
                    .Value;

Documentation: LINQ to JSON

James Newton-King
  • 48,174
  • 24
  • 109
  • 130
I4V
  • 34,891
  • 6
  • 67
  • 79
  • 14
    Just a side note: `.Where(p => p.Name == "url").First()` can just be replaced by `.First(p => p.Name == "url")`. – dav_i Sep 12 '13 at 08:42
  • When you use `dynamic`, no need to use the cast in `(string)obj.picture.data.url`. You can simply write `Console.WriteLine(obj.picture.data.url);` and the correct overload will be invoked at runtime! – Nawaz Sep 13 '13 at 07:04
  • @Nawaz I know, it is only to show that `obj.picture.data.url` is in fact a `JToken` not string. – I4V Sep 13 '13 at 08:07
  • 1
    I think you meant `).Value()` or something like that cause your code won't work. – Royi Namir Nov 04 '14 at 08:53
  • 1
    The use of dynamic should not be recommended if you want your code to be reusable on mobile platforms: http://stackoverflow.com/a/1668642 – Daan Mar 22 '15 at 15:51
  • if you use SimpleJSON you can just do myJSONNode.Linq.Where(x=>x.Value["name"] == "me").FirstOrDefault().Value – B''H Bi'ezras -- Boruch Hashem Apr 04 '19 at 10:51
5

I would not recommend LINQ. I would recommend a JSON library such as newtonsoft.json.

So you can do this:

string json = @"{
  ""Name"": ""Apple"",
  ""Expiry"": "2008-12-28T00:00:00",
  ""Price"": 3.99,
  ""Sizes"": [
    ""Small"",
    ""Medium"",
    ""Large""
  ]
}";

JObject o = JObject.Parse(json);

string name = (string)o["Name"];

// Apple
JArray sizes = (JArray)o["Sizes"];
string smallest = (string)sizes[0];

// Small

Note:- this code has been copied from the samples present on the project site http://james.newtonking.com/pages/json-net.aspx

RvdK
  • 19,580
  • 4
  • 64
  • 107
Parv Sharma
  • 12,581
  • 4
  • 48
  • 80
0

In a bind you could always deserialize the JSON and serialize it to XML, and load the XML in a XDocument. Then you can use the classic Linq to XML. When you are done take the XML, deserialize it, and serialize it back to JSON to JSON. We used this technique to add JSON support to an application that was originally built for XML, it allowed near-zero modifications to get up and running.

Drunken Code Monkey
  • 1,796
  • 1
  • 14
  • 18
0

You can easily query with LINQ like this

considering this JSON

{
    "items": [
        {
            "id": "10",
            "name": "one"
        },
        {
            "id": "12",
            "name": "two"
        }
    ]
}

let's put it in a variable called json like this,

JObject json = JObject.Parse("{'items':[{'id':'10','name':'one'},{'id':'12','name':'two'}]}");

you can select all ids from the items where name is "one" using the following LINQ query

var Ids =
    from item in json["items"]
    where (string)item["name"] == "one"
    select item["id"];

Then, you will have the result in an IEnumerable list

Abraham
  • 12,140
  • 4
  • 56
  • 92