2

I am trying to use the fanart.tv webservice API but have a couple of issues. I am using Json.Net (Newtonsoft.Json) and with other web-services I have de-serialized the JSON reponses into C# objects directly.

The issue here is that the element names are changing. Eg. if I search for artist thumbs for Metallica you get

{"Metallica":{"mbid_id":"65f4f0c5-ef9e-490c-aee3-909e7ae6b2ab","artistthumb":        [{"id":"36181","url":"http://assets.fanart.tv/fanart/music/65f4f0c5-ef9e-490c-aee3-909e7ae6b2ab/artistthumb/metallica-4fd83b0129f83.jpg","likes":"1"},...]}}

So the root element is called Metallica. Obviously search for another artist and you get a different element name. After attempting to deserialize this to an object I gave up and as in reality all I needed was a list of strings (the urls) I tried to process the JSON

  var obj = _downloader.Download<JObject>(url);
  if (obj != null)
  {
    if (obj.HasValues)
    {
      var fanartArtist = (JProperty)obj.First;
      if (fanartArtist.HasValues)
      {
        var thumbs = fanartArtist.Value[SearchSubTypeToString(subType)];
        if (thumbs.HasValues)
        {
          thumbUrls.AddRange(thumbs.Select(thumb => thumb["url"].ToString()));
        }
      }
    }
  }

which works fine when there is a response but if there are no thumbs the web-service returns null and this code fails with

Unable to cast object of type 'Newtonsoft.Json.Linq.JValue' to type 'Newtonsoft.Json.Linq.JObject'.

To complicate matters slightly I am sort of limited by the application and ideally I need to use

JsonConvert.DeserializeObject<TE>(json);

So the question is what what is the best approach to solve both of these issues?

Jameson_uk
  • 432
  • 2
  • 12
  • 1
    The data you're getting actually consists of a dictionary with a single key: `Metallica`, with a value that has all the rest of the data in it. – Bobson Jul 03 '13 at 17:08

1 Answers1

2

Try this:

First, define objects to hold the data deserialized from the JSON:

class Artist
{
    public Guid mb_id { get; set; }
    public List<Thumb> artistthumb { get; set; }
}

class Thumb
{
    public int id { get; set; }
    public string url { get; set; }
    public int likes { get; set; }
}

You can then deserialize it like this (where json is a string containing the JSON data from the web service):

Dictionary<string, Artist> artists = 
          JsonConvert.DeserializeObject<Dictionary<string, Artist>>(json);

Once deserialized, you can access the data like this:

foreach (KeyValuePair<string, Artist> kvp in artists)
{
    Console.WriteLine("Urls for " + kvp.Key + ":");
    foreach (Thumb thumb in kvp.Value.artistthumb)
    {
        Console.WriteLine(thumb.url);
    }
}

Assuming the data you showed in your question, the output would look like this:

Urls for Metallica:
http://assets.fanart.tv/fanart/music/65f4f0c5-ef9e-490c-aee3-909e7ae6b2ab909e7ae6b2ab/artistthumb/metallica-4fd83b0129f83.jpg

.

Brian Rogers
  • 125,747
  • 31
  • 299
  • 300