1

I am working on a WPF MVVM application to retrieve some cryptocurrency information from this API. I am able to call the API and get an HTTP response, however, I am having trouble deserializing this response to an object. I understand that the symbol variable is passed but not used, however, I want the deserialization process to work and then I will format the URI accordingly to include the symbol and the API Key. Here is the code:

Crypto Object

public class Crypto
{
    public string? Symbol { get; set; }
    public string? Name { get; set; }
    public double? Price { get; set; }
    public double? ChangesPercentage { get; set; }
}

API Call Service Interface

public interface ICryptoService
{
    Task<Crypto> GetCrypto(string symbol); 
}

API Call Service

public async Task<Crypto> GetCrypto(string symbol)
    {
        using (HttpClient client = new HttpClient())
        {
            using var response = await client.GetAsync("https://financialmodelingprep.com/api/v3/quote/BTCUSD?apikey=KEY", HttpCompletionOption.ResponseHeadersRead);

            response.EnsureSuccessStatusCode();

            if (response.Content is object && response.Content.Headers.ContentType.MediaType == "application/json")
            {
                var responseStream = await response.Content.ReadAsStreamAsync();

                try
                {
                    return await System.Text.Json.JsonSerializer.DeserializeAsync<Crypto>(responseStream, new System.Text.Json.JsonSerializerOptions { IgnoreNullValues = true, PropertyNameCaseInsensitive = true });
                }
                catch (JsonException)
                {
                    Console.WriteLine("Invalid JSON!");
                }
            }
            else
            {
                Console.WriteLine("HTTP Response cannot be deserialised");
            }

            return null;
        }
    }
}

Main Method

        CryptoService cryptoService = new CryptoService();

        cryptoService.GetCrypto("BTCUSD").ContinueWith((task) =>
        {
            var crypto = task.Result;
        });

I am attaching the JSON response that the link will provide below:

[
 {
"symbol": "BTCUSD",
"name": "Bitcoin USD",
"price": 22887.08,
"changesPercentage": -0.1263,
"change": -28.9473,
"dayLow": 22887.08,
"dayHigh": 23351.51,
"yearHigh": 48086.836,
"yearLow": 15599.047,
"marketCap": 441375461059,
"priceAvg50": 19835.04,
"priceAvg200": 19730.518,
"volume": 27292504064,
"avgVolume": 23965132574,
"exchange": "CRYPTO",
"open": 23267.4,
"previousClose": 23267.4,
"eps": null,
"pe": null,
"earningsAnnouncement": null,
"sharesOutstanding": 19284918,
"timestamp": 1675872360
 }
]

This is the exception that I get whenever I run the code:

Exception thrown: 'System.Text.Json.JsonException' in System.Private.CoreLib.dll
2
  • 3
    The JSON you've got doesn't represent a Crypto object; it represents an array (or list) of objects. Try deserializing to a List<Crypto>. Also, regardless of whether or not that works, you should edit your question to show the full exception, not just the type of it. Commented Feb 8, 2023 at 18:34
  • 1
    Isn't IgnoreNullValues obsolete? Commented Feb 8, 2023 at 18:42

1 Answer 1

1

Your json is a json array, not a single json object, so you need to deserialize to a collection:

var result = await JsonSerializer.DeserializeAsync<List<Crypto>>(...);

P.S.

In general case it is recommended to just await async functions instead of using ContinueWith.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.