Coder Perfect

Newtonsoft (or LINQ to JSON, perhaps?) deserializes JSON to a.NET object.

Problem

I’m aware that there have been a few posts about Newtonsoft, so hopefully this isn’t a rehash… I’m trying to make a nice object out of the JSON data supplied by Kazaa’s API.

WebClient client = new WebClient();
Stream stream = client.OpenRead("http://api.kazaa.com/api/v1/search.json?q=muse&type=Album");
StreamReader reader = new StreamReader(stream);

List<string> list = Newtonsoft.Json.JsonConvert.DeserializeObject<List<string>>(reader.Read().ToString());

foreach (string item in list)
{
    Console.WriteLine(item);
}

//Console.WriteLine(reader.ReadLine());
stream.Close();

That JsonConvert line was the most recent one I was experimenting with… I’m not sure what’s going on, and I was hoping to save some time by asking you guys. I was planning on converting it to a Dictionary or something, but I only need to grab a couple of values, so judging by the documentation, Newtonsoft’s LINQ to JSON might be a better option? Thoughts/Links?

The following is an example of JSON return data:

{
  "page": 1,
  "total_pages": 8,
  "total_entries": 74,
  "q": "muse",
  "albums": [
    {
      "name": "Muse",
      "permalink": "Muse",
      "cover_image_url": "http://image.kazaa.com/images/69/01672812 1569/Yaron_Herman_Trio/Muse/Yaron_Herman_Trio-Muse_1.jpg",
      "id": 93098,
      "artist_name": "Yaron Herman Trio"
    },
    {
      "name": "Muse",
      "permalink": "Muse",
      "cover_image_url": "htt p://image.kazaa.com/images/54/888880301154/Candy_Lo/Muse/Candy_Lo-Muse_1.jpg",
      "i d": 102702,
      "artist_name": "\u76e7\u5de7\u97f3"
    },
    {
      "name": "Absolution",
      "permalink": " Absolution",
      "cover_image_url": "http://image.kazaa.com/images/65/093624873365/Mus e/Absolution/Muse-Absolution_1.jpg",
      "id": 48896,
      "artist_name": "Muse"
    },
    {
      "name": "Ab solution",
      "permalink": "Absolution-2",
      "cover_image_url": "http://image.kazaa.com/i mages/20/825646911820/Muse/Absolution/Muse-Absolution_1.jpg",
      "id": 118573,
      "artist _name": "Muse"
    },
    {
      "name": "Black Holes And Revelations",
      "permalink": "Black-Holes-An d-Revelations",
      "cover_image_url": "http://image.kazaa.com/images/66/093624428466/ Muse/Black_Holes_And_Revelations/Muse-Black_Holes_And_Revelations_1.jpg",
      "id": 48813,
      "artist_name": "Muse"
    },
    {
      "name": "Black Holes And Revelations",
      "permalink": "Bla ck-Holes-And-Revelations-2",
      "cover_image_url": "http://image.kazaa.com/images/86/ 825646911486/Muse/Black_Holes_And_Revelations/Muse-Black_Holes_And_Revelations_1 .jpg",
      "id": 118543,
      "artist_name": "Muse"
    },
    {
      "name": "Origin Of Symmetry",
      "permalink": "Origin-Of-Symmetry",
      "cover_image_url": "http://image.kazaa.com/images/29/825646 912629/Muse/Origin_Of_Symmetry/Muse-Origin_Of_Symmetry_1.jpg",
      "id": 120491,
      "artis t_name": "Muse"
    },
    {
      "name": "Showbiz",
      "permalink": "Showbiz",
      "cover_image_url": "http: //image.kazaa.com/images/68/825646182268/Muse/Showbiz/Muse-Showbiz_1.jpg",
      "id": 60444,
      "artist_name": "Muse"
    },
    {
      "name": "Showbiz",
      "permalink": "Showbiz-2",
      "cover_imag e_url": "http://image.kazaa.com/images/50/825646912650/Muse/Showbiz/Muse-Showbiz_ 1.jpg",
      "id": 118545,
      "artist_name": "Muse"
    },
    {
      "name": "The Resistance",
      "permalink": "T he-Resistance",
      "cover_image_url": "http://image.kazaa.com/images/36/825646864836/ Muse/The_Resistance/Muse-The_Resistance_1.jpg",
      "id": 121171,
      "artist_name": "Muse"
    }
  ],
  "per_page": 10
}

I conducted some additional research and discovered that Newtonsoft’s LINQ to JSON, which uses WebClient, Stream, StreamReader, and Newtonsoft, is just what I needed… I can get JSON data from Kazaa, extract a URL, and download the file in about seven lines of code! It’s fantastic.

WebClient client = new WebClient();
Stream stream = client.OpenRead("http://api.kazaa.com/api/v1/search.json?q=muse&type=Album");
StreamReader reader = new StreamReader(stream);

Newtonsoft.Json.Linq.JObject jObject = Newtonsoft.Json.Linq.JObject.Parse(reader.ReadLine());

// Instead of WriteLine, 2 or 3 lines of code here using WebClient to download the file
Console.WriteLine((string)jObject["albums"][0]["cover_image_url"]);
stream.Close();

Because this topic has so many views, I felt it would be beneficial to include the “using” sections discussed in the comments.

using(var client = new WebClient())
using(var stream = client.OpenRead("http://api.kazaa.com/api/v1/search.json?q=muse&type=Album"))
using (var reader = new StreamReader(stream))
{
    var jObject = Newtonsoft.Json.Linq.JObject.Parse(reader.ReadLine());
    Console.WriteLine((string) jObject["albums"][0]["cover_image_url"]);
}

Asked by J Benjamin

Solution #1

To make things easier, you can utilize the C# dynamic type. Because it does not rely on magic-strings, this technique makes refactoring easier.

JSON

The JSON string below is a simple HTTP API response that defines two properties: Id and Name.

{"Id": 1, "Name": "biofractal"}

C#

To deserialize this string into a dynamic type, use JsonConvert.DeserializeObjectdynamic>(), then access its properties as usual.

dynamic results = JsonConvert.DeserializeObject<dynamic>(json);
var id = results.Id;
var name= results.Name;

The property values will correctly deserialize if you define the type of the results variable as dynamic rather than using the var keyword, e.g. Id to an int rather than a JValue (thanks to GFoley83 for the comment below).

The Newtonsoft assembly can be found at http://nuget.org/packages/newtonsoft.json.

Package: You can also use the nuget live installer to add the package to your project. Simply open your project and browse for the package, then install, uninstall, and update it. It will be added to your project under Dependencies/NuGet.

Answered by biofractal

Solution #2

I would utilize Json.LINQ NET’s to JSON JObject class if you only require a few things from the JSON object. Consider the following scenario:

JToken token = JObject.Parse(stringFullOfJson);

int page = (int)token.SelectToken("page");
int totalPages = (int)token.SelectToken("total_pages");

This method appeals to me because it eliminates the requirement to entirely deserialize the JSON object. This is useful for APIs like Twitter, which might occasionally surprise you with missing object properties.

Serializing and Deserializing JSON with Json.NET and LINQ to JSON with Json.NET documentation

Answered by arcain

Solution #3

It’s really simple to parse any object of this kind using the dynamic keyword:

dynamic x = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonString);
var page = x.page;
var total_pages = x.total_pages
var albums = x.albums;
foreach(var album in albums)
{
    var albumName = album.name;

    // Access album data;
}

Answered by Sushant Srivastava

Solution #4

Please correct me if I’m wrong, but I feel the previous example is slightly out of date with the latest version of James Newton’s Json.NET module.

var o = JObject.Parse(stringFullOfJson);
var page = (int)o["page"];
var totalPages = (int)o["total_pages"];

Answered by Rick Leitch

Solution #5

If you’re like me and like to work with tightly typed objects**, use:

MyObj obj =  JsonConvert.DeserializeObject<MyObj>(jsonString);

You can use intellisense and compile-time type error checking this way.

By copying your JSON into memory and pasting it as JSON objects (Visual Studio -> Edit -> Paste Special -> Paste JSON as Classes), you can quickly generate the appropriate classes.

If you don’t have that option in Visual Studio, look here.

You must also ensure that your JSON is valid. If it’s merely an array of objects, add your own object at the beginning. “obj”:[,,] is an example.

** I understand that dynamic makes things easier at times, but I’m stuck in my ways with this.

Answered by Guy Lowe

Post is based on https://stackoverflow.com/questions/4749639/deserializing-json-to-net-object-using-newtonsoft-or-linq-to-json-maybe