Home > database >  How to deserialize this JSON to a List?
How to deserialize this JSON to a List?

Time:01-04

I have an issue with deserializing the JSON file from the web to a List.

My code is down below, but it does not execute and shows System.NullReferenceException. It happens in the Content() method, when I call callApiAsync() in the List.

static void Main(string[] args)
        {
            Content();
            Console.ReadKey();
        }

        private async static void Content()
        {
            List<Coin> coins = await callApiAsync();

            for (int i = 0; i < coins.Count; i  )
            {
                Console.WriteLine(coins[i].price);
            }
        }

        static async Task<List<Coin>> callApiAsync()
        {
            string url = "https://api.coinstats.app/public/v1/charts?period=all&coinId=bitcoin";

            HttpClient httpClient = new HttpClient();

            var httpResponse = await httpClient.GetAsync(url);
            string jsonResponse = await httpResponse.Content.ReadAsStringAsync();

            var data = JsonConvert.DeserializeObject<Root>(jsonResponse);
            return data.coins;
        }
    }

public class Root
    {
        public List<Coin> coins { get; set; }
    }

    public class Coin
    {
        public int time { get; set; }
        public int price { get; set; }
    }

My JSON for example: {"chart":[[1372032000,107.979,1,0],[1372118400,102.982,1,0],[1372204800,103.34,1,0]]}

CodePudding user response:

The sample JSON you gave:

{"chart":[[1372032000,107.979,1,0],[1372118400,102.982,1,0],[1372204800,103.34,1,0]]}

Does not have a type that matches the "Root" class you are trying to deserialize to.

You can paste your JSON into a site like https://json2csharp.com/ to find out what the corresponding C# class should look like. In this case, the Root class should look like the following to support deserializing the specified JSON:

public class Root
{
    public List<List<double>> chart { get; set; }
}

My guess is that you then intend to interpret the first value in each list as some sort of time stamp, the second value as a "price", and ignore the second and third values in each list. You will have to do the legwork for this after first deserializing the JSON to a list of lists of doubles.

For example:

var data = JsonConvert.DeserializeObject<Root>(jsonResponse);
return data.chart.Select(listOfDoubles => new Coin
{
    time = (int)listOfDoubles[0],
    price = listOfDoubles[1]
}).ToList();

CodePudding user response:

You only need one string of code to deserialize

return JObject.Parse(jsonResponse)["chart"]
.Select(x => new Coin { time = UnixSecondsToDateTime( (long) x[0]), 
                        price = (decimal)x[1] }
        ).ToList();


public class Coin
{
    public DateTime time { get; set; }
    public decimal price { get; set; }
}

public static DateTime UnixSecondsToDateTime(long timestamp, bool local = false)
{
    var offset = DateTimeOffset.FromUnixTimeSeconds(timestamp);
    return local ? offset.LocalDateTime : offset.UtcDateTime;
}
  • Related