Helmuteke Helmuteke - 17 days ago 7
C# Question

Getting an exception when trying to deserialize JSON and display the results in a DataGridView

I have some C# code where I get JSON data from an API. The JSON looks like this:

"count": 32696,
"results": [{
"data_id": 0,
"name": "Extended Potion of Ghost Slaying",
"rarity": 0,
"restriction_level": 0,
"img": "",
"type_id": 0,
"sub_type_id": 0,
"price_last_changed": "2013-03-18 17:00:31 UTC",
"max_offer_unit_price": 0,
"min_sale_unit_price": 0,
"offer_availability": 0,
"sale_availability": 0,
"sale_price_change_last_hour": 0,
"offer_price_change_last_hour": 0

(There is more than just one item in the results though.)

I have made 2 classes like this:

internal class MyClass
public int data_id { get; set; }
public string name { get; set; }
public int rarity { get; set; }
public int restriction_level { get; set; }
public string img { get; set; }
public int type_id { get; set; }
public int sub_type_id { get; set; }
public string price_last_changed { get; set; }
public int max_offer_unit_price { get; set; }
public int min_sale_unit_price { get; set; }
public int offer_availability { get; set; }
public int sale_availability { get; set; }
public int sale_price_change_last_hour { get; set; }
public int offer_price_change_last_hour { get; set; }

internal class RootObject
public int count { get; set; }
public List<MyClass> results { get; set; }

And here is the part where I get the JSON and deserialize it:

using (WebClient wc = new WebClient())
string URI = "a good url";

wc.Headers.Add("Content-Type", "text");
string HtmlResult = wc.DownloadString(URI);
MyClass[] result = JsonConvert.DeserializeObject<MyClass[]>(HtmlResult);
DataTable dt = (DataTable)JsonConvert.DeserializeObject(HtmlResult, (typeof(DataTable)));
this.dataGridView1.DataSource = dt;

But when I run this code I get an error:

Additional information: Cannot deserialize the current JSON object
(e.g. {"name":"value"}) into type 'gwspiderv2.MyClass[]' because the
type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.

I already use this type of code on another API without errors. What am I doing wrong?


In your code it seems you are trying to deserialize the same JSON two different ways, which doesn't make a whole lot of sense:

MyClass[] result = JsonConvert.DeserializeObject<MyClass[]>(HtmlResult);
DataTable dt = (DataTable)JsonConvert.DeserializeObject(HtmlResult, (typeof(DataTable)));

You are getting the first error (in your question) because your JSON represents a single object, but you are trying to deserialize it into an array of MyClass. You have defined a RootObject class, but you are not using it. It seems that you should be, because it fits your JSON.

You are getting the second error (in the comments to @inan's answer) because the JSON is in the wrong format to be deserialized into a DataTable. Presumably you are trying to do that so you can display the data in your DataGridView. But you don't need to convert it to a DataTable in order to use it as a data source. You can just give your DataGridView an IList, which you already have in your RootObject.

Change your code to this:

RootObject result = JsonConvert.DeserializeObject<RootObject>(HtmlResult);
this.dataGridView1.DataSource = result.results;