JonnyBravoJr
JonnyBravoJr

Reputation: 338

Deserialize JSON data in C#

I am new to working with JSON data and I'm trying to deserialize pricing data from the AWS website. I've built out my classes (I did a Paste Special > Paste JSON data as classes) but when I attempt to deserialize, it balks when it comes to the Config class. I believe I either need to create a dictionary or do a List but am not sure how to nest this correctly. I've tried different things but nothing seems to work. Pointing me in the right direction so I can figure it out is much appreciated.

    public class Rootobject
    {
        public float vers { get; set; }
        public Config config { get; set; }
    }

    public class Config
    {
        public string rate { get; set; }
        public string valueColumns { get; set; }
        public string currencies { get; set; }
        public Region regions { get; set; }
    }

    public class Region
    {
        public string region { get; set; }
        public Instancetype instanceTypes { get; set; }
    }

    public class Instancetype
    {
        public string type { get; set; }
        public Size sizes { get; set; }
    }

    public class Size
    {
        public string size { get; set; }
        public string vCPU { get; set; }
        public string ECU { get; set; }
        public string memoryGiB { get; set; }
        public string storageGB { get; set; }
        public Valuecolumn valueColumns { get; set; }
    }

    public class Valuecolumn
    {
        public string name { get; set; }
        public Prices prices { get; set; }
    }

    public class Prices
    {
        public string USD { get; set; }
    }



   private static T _download_serialized_json_data<T>(string url) where T : new() {
  using (var w = new WebClient()) {
    var json_data = string.Empty;
    // attempt to download JSON data as a string
    try {
      json_data = w.DownloadString(url);
    }
    catch (Exception) {}
    // if string with JSON data is not empty, deserialize it to class and return its instance 
    return !string.IsNullOrEmpty(json_data) ? JsonConvert.DeserializeObject<T>(json_data) : new T();
  }
}

Upvotes: 0

Views: 191

Answers (1)

steve16351
steve16351

Reputation: 5812

If I take the JSON from here and apply your classes,

https://a0.awsstatic.com/pricing/1/deprecated/ec2/pricing-on-demand-instances.json

Generally the problem seems to be in the JSON it is specifying an array of values, but your class(es) only expect a single key/value.

For example, for your config class (I've cut down the JSON and class for brevity), the JSON looks like this,

{
"vers": 0.01,
"config": {
    "rate": "perhr",
    "valueColumns": [
        "linux",
        "windows"
    ]
}
}

But your class looks like this,

public class Config
{
    public string rate { get; set; }
    public string valueColumns { get; set; }
}

So your valueColumns is only expecting a single value, not an array of them. In the JSON you can see it is an array due to the [ and ] that wrap the entries of value columns. If you try and deserialise you'll get an exception such as..:

Additional information: Error reading string. Unexpected token: StartArray. Path 'config.valueColumns', line 5, position 22.

Basically saying, I'm seeing the start of an array but I'm not expecting one. So to fix that you can simply change that property to an array in your class, as follows.

public class Config
{
    public string rate { get; set; }
    public string[] valueColumns { get; set; }
}

Upvotes: 2

Related Questions