Unable to deserialize JSON array to type - Json.NET

I am trying to deserialize json data into a model class, but I fail. That's what I'm doing:

public CountryModel GetCountries() { using (WebClient client = new WebClient()) { var result = client.DownloadString("http://api.worldbank.org/incomeLevels/LIC/countries?format=json"); var output = JsonConvert.DeserializeObject<List<CountryModel>>(result); return output.First(); } } 

This is what my model looks like:

 public class CountryModel { public int Page { get; set; } public int Pages { get; set; } public int Per_Page { get; set; } public int Total { get; set; } public List<Country> Countries { get; set; } } public class Country { public int Id { get; set; } public string Iso2Code { get; set; } public string Name { get; set; } public Region Region { get; set; } } public class Region { public int Id { get; set; } public string Value { get; set; } } 

You can see Json, I am here: http://api.worldbank.org/incomeLevels/LIC/countries?format=json

This is the error I get:

Unable to deserialize JSON array to type "Mvc4AsyncSample.Models.CountryModel". Line 1, position 1.

+9
json c # serialization
Feb 26 2018-12-12T00:
source share
3 answers

You need to write a custom JsonConverter :

  public class CountryModelConverter : JsonConverter { public override bool CanConvert(Type objectType) { if (objectType == typeof(CountryModel)) { return true; } return false; } public override object ReadJson(JsonReader reader, Type objectType , object existingValue, JsonSerializer serializer) { reader.Read(); //start array //reader.Read(); //start object JObject obj = (JObject)serializer.Deserialize(reader); //{"page":1,"pages":1,"per_page":"50","total":35} var model = new CountryModel(); model.Page = Convert.ToInt32(((JValue)obj["page"]).Value); model.Pages = Convert.ToInt32(((JValue)obj["pages"]).Value); model.Per_Page = Int32.Parse((string) ((JValue)obj["per_page"]).Value); model.Total = Convert.ToInt32(((JValue)obj["total"]).Value); reader.Read(); //end object model.Countries = serializer.Deserialize<List<Country>>(reader); reader.Read(); //end array return model; } public override void WriteJson(JsonWriter writer, object value , JsonSerializer serializer) { throw new NotImplementedException(); } } 

And mark CountryModel this converter (I also had to switch some int to string ):

  [JsonConverter(typeof(CountryModelConverter))] public class CountryModel { public int Page { get; set; } public int Pages { get; set; } public int Per_Page { get; set; } public int Total { get; set; } public List<Country> Countries { get; set; } } public class Country { public string Id { get; set; } public string Iso2Code { get; set; } public string Name { get; set; } public Region Region { get; set; } } public class Region { public string Id { get; set; } public string Value { get; set; } } 

You can then deserialize it as follows:

 var output = JsonConvert.DeserializeObject<CountryModel>(result); 
+17
Feb 26 2018-12-12T00:
source share

It looks like a (not very good) attempt to represent XML in JSON. JSON looks like this:

 [ { "page": 1, … }, [ { "id": "AFG", "name": "Afghanistan", … }, { "id": "BDI", "name": "Burundi", … }, … ] ] 

While reasonable JSON (which, by the way, will map well with your model) will look like this:

 { "page": 1, …, "countries": [ { "id": "AFG", "name": "Afghanistan", … }, { "id": "BDI", "name": "Burundi", … }, … ] } 

If you are sure that you want to use JSON (and not XML), you can do this by first deserializing JSON into the JSON.NET object model and then deserializing it in your model:

 var json = client.DownloadString("http://api.worldbank.org/incomeLevels/LIC/countries?format=json"); var array = (JArray)JsonConvert.DeserializeObject(json); var serializer = new JsonSerializer(); var countryModel = serializer.Deserialize<CountryModel>(array[0].CreateReader()); countryModel.Countries = serializer.Deserialize<List<Country>>(array[1].CreateReader()); return countryModel; 

Remember to change the Id properties to string , because that is what they are.

+12
Feb 26 2018-12-12T00:
source share

Your model does not match the JSON structure. It looks like you are missing the last 6 properties.

 { "id": "AFG", "iso2Code": "AF", "name": "Afghanistan", "region": { "id": "SAS", "value": "South Asia" }, "adminregion": { "id": "SAS", "value": "South Asia" }, "incomeLevel": { "id": "LIC", "value": "Low income" }, "lendingType": { "id": "IDX", "value": "IDA" }, "capitalCity": "Kabul", "longitude": "69.1761", "latitude": "34.5228" 

}

-one
Feb 27 '12 at 6:15
source share



All Articles