Search code examples
c#jsonapijson.netdeserialization

Getting Errors when trying to Deserialize JSON object from API call in C#. (currency exchange)


My goal is to build an API that can load currency data from https://openexchangerates.org/ api into our SQLite database. I am able to get the JSON object formatted like this:

enter image description here

When i run the code below, it returns an errors. I am not sure how to resolve this. Just need to convert this JSON into a C# class without error.

Here's the custom C# object to mapped to JSON obj:

     public class ExchangeRate
    {
        public string Disclaimer { get; set; }
        public string License { get; set; }
        public string Timestamp { get; set; }
        public string Base { get; set; }
        public string Rates { get; set; }
    }

Here is the api call where its returning the error:

public static async Task<List> GetLatest(string url) {

        var client = new HttpClient();
        string results = await client.GetStringAsync(url);
        List<ExchangeRate> ratesList = JsonConvert.DeserializeObject<List<ExchangeRate>>(results);
        return ratesList;
    }

error msg


Solution

  • The example JSON is not a list, it's a single object, this is specified in the exception message

    ...because the type requires a JSON array

    , otherwise it would have [ ] around it indicating an array (can be deserialized to list). Also, your model is flawed as Rates is not a string, but an object, and Timestamp is not a string but a long for the datetime as ticks. Change your model like so:

    public class ExchangeRate
    {
        //decorate your properties since the json string uses lowercase
        [JsonProperty("disclaimer")]
        public string Disclaimer { get; set; }
        [JsonProperty("license")]
        public string License { get; set; }
        [JsonProperty("timestamp")]
        public long Timestamp { get; set; }
        [JsonProperty("base")]
        public string Base { get; set; }
        [JsonProperty("rates")]
        public Rates Rates { get; set; }
    }
    
    public class Rates 
    {
        //create the properties for the Rates class
    }
    

    OR make the rates property a Dictionary<string, decimal>, NOTE: this could fail if any key is duplicated.

    public class ExchangeRate
    {
        //decorate your properties since the json string uses lowercase
        [JsonProperty("disclaimer")]
        public string Disclaimer { get; set; }
        [JsonProperty("license")]
        public string License { get; set; }
        [JsonProperty("timestamp")]
        public long Timestamp { get; set; }
        [JsonProperty("base")]
        public string Base { get; set; }
        [JsonProperty("rates")]
        public Dictionary<string, decimal> Rates { get; set; }
    }
    

    Change your code to this:

    ExchangeRate rate = JsonConvert.DeserializeObject<ExchangeRate>(results);