1

I am attempting to map a JSON string being returned to me into a .Net model class that I have. The JSON is going to be an array of any number of results, and I would like to return a List<MyObject> from this method.

The JSON looks like this:

{
  "artists" : {
    "href" : "https://api.spotify.com/v1/search?query=tania+bowra&offset=0&limit=20&type=artist",
    "items" : [ {
      "external_urls" : {
        "spotify" : "https://open.spotify.com/artist/08td7MxkoHQkXnWAYD8d6Q"
      },
      "followers" : {
        "href" : null,
        "total" : 26
      },
      "genres" : [ ],
      "href" : "https://api.spotify.com/v1/artists/08td7MxkoHQkXnWAYD8d6Q",
      "id" : "08td7MxkoHQkXnWAYD8d6Q",
      "images" : [ {
        "height" : 640,
        "url" : "https://i.scdn.co/image/f2798ddab0c7b76dc2d270b65c4f67ddef7f6718",
        "width" : 640
      }, {
        "height" : 300,
        "url" : "https://i.scdn.co/image/b414091165ea0f4172089c2fc67bb35aa37cfc55",
        "width" : 300
      }, {
        "height" : 64,
        "url" : "https://i.scdn.co/image/8522fc78be4bf4e83fea8e67bb742e7d3dfe21b4",
        "width" : 64
      } ],
      "name" : "Tania Bowra",
      "popularity" : 2,
      "type" : "artist",
      "uri" : "spotify:artist:08td7MxkoHQkXnWAYD8d6Q"
    } ],
    "limit" : 20,
    "next" : null,
    "offset" : 0,
    "previous" : null,
    "total" : 1
  }
}

I am attempting to use Json.Net for this ... so I began with:

JObject jsonArtists = JObject.Parse(content);

This is where I am stuck. I have tried different approaches using a JArray but am not sure exactly what syntax I need to use here, and how much of the lifting is going to be handled by Json.Net versus having to write out all of the various property mappings.

In this case I am interested in getting an array from the items collection in the JSON and get this into a List<MyObject>.

Patrick
  • 5,526
  • 14
  • 64
  • 101
  • 2
    It looks like you want to use `JsonConvert.DeserializeObject`, if your model matches the JSON directly... – Jon Skeet Jan 28 '16 at 23:05
  • This is where I got hung up on JArray because I am getting " Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[VoteYourMusic.Spotify.Artist]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly." – Patrick Jan 28 '16 at 23:10
  • Well yes, your `artists` value isn't an array... you should either change your model or change the JSON to match it. – Jon Skeet Jan 28 '16 at 23:11
  • Ok thanks I see what you're saying. I need that "items" array under the "artists" node converted into my List<>. – Patrick Jan 28 '16 at 23:35
  • So if you want to make life easy, create a class with an Items property in it... Then you can map it to a better model class if you want to. – Jon Skeet Jan 28 '16 at 23:38
  • "need that "items" array under the "artists" node converted into my List<>" > `JObject.Parse(json)["artist"]["items"].ToObject>()` but it's not even close to be fail proof :) – dmay Jan 29 '16 at 00:43

3 Answers3

0

You need to create classes to represent the JSON Data. After that, deserialize the JSON Data into the classes.

Resources you should look at:

Community
  • 1
  • 1
Kody
  • 905
  • 9
  • 19
  • Have you looked at the resources I provided? It shows many helpful examples that could help you in your particular issue. – Kody Jan 28 '16 at 23:15
  • I advise against Json.NET, use [(System.Web.Extensions) System.Web.Script.Serialization.JavaScriptSerializer](https://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer(v=vs.110).aspx) if you are using .NET 3.5+. – Kody Jan 28 '16 at 23:22
  • Thanks, I'll take a look. I'm using 4.6.1. – Patrick Jan 28 '16 at 23:36
  • @Kody: *Why* do you advise against json.net? Without any reasons whatsoever, that's not very compelling. (I think even MS is using json.net for the most part these days, e.g. for .net core...) – Jon Skeet Jan 28 '16 at 23:39
  • @JonSkeet, the JavaScriptSerializer comes with .NET 3.5+ and is lighter than Json.NET. Json.NET is loaded with features that aren't necessary to this requirement. All he needs to do is deserialize into an object. – Kody Jan 29 '16 at 00:06
  • @Kody: Lighter in what terms? If it's just features, just don't use what you don't need. I'll have to check, but iirc json.net is a lot more efficient than JavaScriptSerializer. Not needing an extra package is about the only thing JSS has going for it, IMO. – Jon Skeet Jan 29 '16 at 06:07
0

I went with the following solution to jump straight to the array before attempting to serialize into my object. It works.

    var jsonArtists = JObject
        .Parse(content)
        .SelectToken("artists.items")
        .ToObject<List<MyObject>>();
Patrick
  • 5,526
  • 14
  • 64
  • 101
-1

JSON in your example is a single object ( {...} ), not a list ( [...]).

You can use JsonConvert.DeserializeObject<MyObject>(json) to get straight to your model. Or JsonConvert.DeserializeObject<List<MyObject>>(json) if json contains list definition.

dmay
  • 1,340
  • 8
  • 23