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;
}