Search code examples
c#json.netconsole

Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON array


I am new to APIs and for the past couple of days I have been practising using pre-made ones from GitHub and such. Now I have decided to try and create my own Coronavirus Tracker App (quite original). I have ran into the titled problem and have not found a solution online on how to fix it. I guess the JSON I am trying to receive (https://api.covid19api.com/live/country/germany) is an array and I cannot get it to work. I have tried the same thing on a non array JSON (reddit's) and it works like a charm. All of the code and classes are pasted below and thank you to anyone that takes the time to read this and decides to help.

Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Covid.Api.CovidStats' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array. Path '', line 1, position 1.'

using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;


namespace Covid.Api
{


public class CovidClient
{

    public async Task<CovidStats> GetByCountryLiveStats(string country,DateTime startDate,DateTime endDate)
    {
        var url = $"https://api.covid19api.com/country/{country}/status/confirmed/live?from={startDate}&to={endDate}";
        var client = new HttpClient();
        var response = await client.GetStringAsync(url);
        return JsonConvert.DeserializeObject<CovidStats>(response);
        
    }

}

public class CovidStats
{ 
    [JsonProperty("Country")]
    public string Country { get; set; }
    [JsonProperty("Cases")]
    public int Cases { get; set; }
    [JsonProperty("Status")]
    public string Status { get; set; }
    [JsonProperty("Date")]
    public DateTime date { get; set; }
}
public class CovidList
{
    List<CovidStats> lista { get; set; }
}


}

Solution

  • The API returns a List<T> not a single object so you need to update the Deserialize line:

    return JsonConvert.DeserializeObject<List<CovidStats>>(response);
    

    UPDATE:

    For completeness, you will also need to update the return type of the method. Full code below:

    public static async Task<List<CovidStats>> GetByCountryLiveStats(string country, DateTime startDate, DateTime endDate)
    {
       var url =  $"https://api.covid19api.com/country/{country}/status/confirmed/live?from= {startDate}&to={endDate}";
       var client = new HttpClient();
       var response = await client.GetStringAsync(url);
       return JsonConvert.DeserializeObject<List<CovidStats>>(response);
    }