1

Question Background:

I am calling the Amazon Product Advertising API and receiving from their service a list of products in a JSON format.

The Issue:

Sadly the JSON response varies depending on the parameters supplied to the API. For example: searching for 'Sporting Goods' gives a slightly different response to 'Watches'.

The following gives a very simple example of the differences:

Sporting Goods JSON as received from the API:

{
    "Item": {
        "ID": "145",
        "Title": "Football",
        "ImageUrl": "http://amazon.com/football.jpg",
        "Shipping": "UK",
        "ListPrice": "7.99"
    }
}

Watches JSON as received from the API:

{
    "Item": {
        "ID": "567",
        "Title": "RolexWatch",
        "ImageUrl": "http://amazon.com/RolexWatch.jpg",
        "Shipping": "UK",
        "ListPrice": "£7000.00",
        "SalePrice": "£6500.00"   <------------- extra item in Watches JSON
    }
}

I am currently using NewtonSoft To deserialize the two responses into two distinct C# models i.e:

 public class SportingGoods
    {
      public string ID {set;get;}
      public string Title {set;get;}
      public string ImagesUrl {set;get;}
      public string Shipping{set;get;}
      public string ListPrice{set;get;}
    }

public class Watches
    {
      public string ID {set;get;}
      public string Title {set;get;}
      public string ImagesUrl {set;get;}
      public string Shipping{set;get;}
      public string ListPrice{set;get;}
      public string SalePrice{set;get;}
    }

I am finding there are other variations in the JSON response from the Amazon API. How can I handle this desearlization properly when the JSON data varies so much? I cant keep creating different models when I'm not 100% sure what the JSON will look like.

user1352057
  • 3,162
  • 9
  • 51
  • 117

2 Answers2

4

You can use a dynamic type in C# using JObject.Parse() You'll just have to be careful using it as fields may or may not be present.

dynamic foo = JObject.Parse(jsonText);
string bar = foo.Bar; // bar = "something"
Jared Dykstra
  • 3,596
  • 1
  • 13
  • 25
1

In the example you gave, it looks like the only difference between the two models is that one has SalePrice field while the other does not. Otherwise, they are identical. This scenario is actually pretty common and is not a big deal to handle.

By default, JSON.Net will skip over class members for which there is no corresponding field in the JSON, or vice versa. So you could simply define a single Product model that has all of the possible product fields you're interested in and use it for both of these cases. In the case of sporting goods, the SalePrice will simply be null. If there's an extra field that turns up in the JSON later that you don't really care about, no problem--it will be ignored.

public class Product
{
    public string ID { get; set; }
    public string Title { get; set; }
    public string ImagesUrl { get; set; }
    public string Shipping { get; set; }
    public string ListPrice { get; set; }
    public string SalePrice { get; set; }
}

Now, if your JSON varies more wildly, for example if a field is sometimes a string and sometimes a list of strings, then you have to start looking at other approaches. One possibility is writing a custom JsonConverter to handle the differences. Another possibility is deserializing into a JObject or dynamic instead of using strongly-typed classes.

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