raintrooper
raintrooper

Reputation: 119

Error consuming Web API with ASP.NET MVC - "Cannot deserialize the current JSON object"

I am consuming a Web API, but when serializing I get this error:

Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Covid.Models.RegionsModel]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object. Path 'data', line 1, position 8.

I read several possible solutions, in questions that have already been asked but could not get it to work.

JSON.NET DeserializeObject to List of Objects

Cannot deserialize the current JSON object (e.g. {"name":"value"})

If you could help me please, I have really tried for 3 days but I can't solve it.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using System.Net.Http;
using Covid.Models;
using System.Net.Http.Headers;
using Newtonsoft.Json;

namespace Covid.Controllers
{
    public class HomeController : Controller
    {
        string Baseurl = "https://covid-19-statistics.p.rapidapi.com/regions";

        public async Task<ActionResult> Index()
        {
            try
            {
                List<RegionsModel> region = new List<RegionsModel>();

                using (var client = new HttpClient())
                {
                    client.BaseAddress = new Uri(Baseurl);
                    client.DefaultRequestHeaders.Add("x-rapidapi-key", "32ac4c9518msh7fb8f6c7a05eb7bp1178dbjsn193f09c779d6");
                    client.DefaultRequestHeaders.Add("x-rapidapi-host", "covid-19-statistics.p.rapidapi.com");
                    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                    HttpResponseMessage Res = await client.GetAsync("regions");

                    if (Res.IsSuccessStatusCode)
                    {
                        var response = Res.Content.ReadAsStringAsync().Result;
                        //var ObjMovmientos = JsonConvert.DeserializeObject<List<RegionsModel>>(response);
                        var objResponse1 = JsonConvert.DeserializeObject<List<RegionsModel>>(response);
                        region = objResponse1;
                    }

                    return View(region);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }          
        }
    }
}

The model class is:

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Covid.Models
{
    public class RegionsModel
    {
        public RegionModel[] data { get; set; }  

        public class RegionModel
        {
            [JsonProperty("iso")]
            public string Iso { get; set; }

            [JsonProperty("name")]
            public string Name { get; set; }
        }
    }
}

The JSON is:

{
    "data": [
        {
            "iso": "CHN",
            "name": "China"
        },
        {
            "iso": "TWN",
            "name": "Taipei and environs"
        },
        {
            "iso": "USA",
            "name": "US"
        },
        {
            "iso": "JPN",
            "name": "Japan"
        },
        {
            "iso": "WSM",
            "name": "Samoa"
        }
    ]
}

Upvotes: 0

Views: 1432

Answers (2)

Jawad
Jawad

Reputation: 11364

Change this line,

 var objResponse1 = JsonConvert.DeserializeObject<List<RegionsModel>>(response);

To

 var objResponse1 = JsonConvert.DeserializeObject<RegionsModel>(response);

Reason is because your json is of an object, data ,that has an array of objects...

Upvotes: 1

Andy
Andy

Reputation: 13547

RegionsModel already contains a property that defines an array, so this is wrong:

var objResponse1 = JsonConvert.DeserializeObject<List<RegionsModel>>(response);

It should be:

var objResponse1 = JsonConvert.DeserializeObject<RegionsModel>(response);

Also, your method is already asynchronous. So instead of this:

var response = Res.Content.ReadAsStringAsync().Result;

Do this:

var response = await Res.Content.ReadAsStringAsync();

Finally, change this:

List<RegionsModel> region = new List<RegionsModel>();
// ...
region = objResponse1;

To this:

List<RegionModel> region = new List<RegionModel>();
// ...
region = objResponse1.data.ToList();

Upvotes: 2

Related Questions