简体   繁体   中英

Unable to deserialize JSON data into a List<T>

If candles.json does not exists or it exists and the first element's start date and the last element's end date are different, it will serialize the data to List<IBinanceKline> and create candles.json . If candles.json exists, it should read it and deserialize the data into List<IBinanceKline> . Right now, it is only unable to DeserializeObject<List<IBinanceKline>> with the following error message:

Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON array (eg [1,2,3]) into type 'Binance.Net.Interfaces.IBinanceKline' because the type requires a JSON object (eg {"name":"value"}) to deserialize correctly. To fix this error either change the JSON to a JSON object (eg {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (eg 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 '[0]', line 1, position 2.'

The funny thing is that the code used to work before they updated the library and now it uses IBinanceKline instead of BinanceKline.

candles.json looks like so:

[[1598918400000,0.02916000,0.02933000,0.02805000,0.02840000,160360176.00000000,1598920199999,4581586.82491700,8467,65052915.90000000,1858526.79404600,0.0],[1598920200000,0.02841000,0.02875000,0.02832000,0.02867000,58358821.40000000,1598921999999,1666101.98325900,3117,22117012.60000000,631314.89648100,0.0]]
List<IBinanceKline> candlesFromFile = null;
if (File.Exists(CandlesFile))
{
    var content = File.ReadAllText(CandlesFile);
    candlesFromFile = JsonConvert.DeserializeObject<List<IBinanceKline>>(content); // Exception thrown here
}

List<IBinanceKline> candles;
if (candlesFromFile != null && candlesFromFile.First().OpenTime == StartDate && candlesFromFile.Last().OpenTime == EndDate)
{
    candles = candlesFromFile;
}
else
{
    candles = GetCandlesByStartDateEndDate(symbol, interval, StartDate, EndDate);

    string serializedObject = JsonConvert.SerializeObject(candles);
    File.WriteAllText(CandlesFile, serializedObject);
}

private List<IBinanceKline> GetCandlesByStartDateEndDate(string symbol, KlineInterval interval, DateTime startDate, DateTime endDate)
{
    if (endDate.Date > DateTime.UtcNow.Date)
        throw new ArgumentOutOfRangeException("The end date is greater than today.");

    var candles = _client.Spot.Market.GetKlines(symbol, interval, startTime: startDate, endTime: endDate, limit: 200).Data.ToList();

    while (endDate > candles.Last().OpenTime)
    {
        var moreCandles = _client.Spot.Market.GetKlines(symbol, interval, startTime: candles.Last().OpenTime, endTime: endDate, limit: 1000).Data.ToList();
        candles.AddRange(moreCandles.ExceptUsingJsonCompare(candles));
    }

    return candles;
}
public interface IBinanceKline
{
    DateTime OpenTime { get; set; }
    decimal Open { get; set; }
    decimal High { get; set; }
    decimal Low { get; set; }
    decimal Close { get; set; }
    decimal BaseVolume { get; set; }
    DateTime CloseTime { get; set; }
    decimal QuoteVolume { get; set; }
    int TradeCount { get; set; }
    decimal TakerBuyBaseVolume { get; set; }
    decimal TakerBuyQuoteVolume { get; set; }
}

Thanks for your comments, the problem occurred because List<IBinanceKline> doesn't really specify which class it will serialize to. In fact, it did serialize to List<BinanceSpotKline> instead.

Solution:

List<BinanceSpotKline> candlesFromFile = null;
if (File.Exists(CandlesFile))
{
    var content = File.ReadAllText(CandlesFile);
    candlesFromFile = JsonConvert.DeserializeObject<List<BinanceSpotKline>>(content);
}

List<BinanceSpotKline> candles;
if (candlesFromFile != null && candlesFromFile.First().OpenTime == StartDate && candlesFromFile.Last().OpenTime == EndDate)
{
    candles = candlesFromFile;
}
else
{
    candles = GetCandlesByStartDateEndDate(symbol, interval, StartDate, EndDate);

    string serializedObject = JsonConvert.SerializeObject(candles);
    File.WriteAllText(CandlesFile, serializedObject);
}

private List<BinanceSpotKline> GetCandlesByStartDateEndDate(string symbol, KlineInterval interval, DateTime startDate, DateTime endDate)
{
    if (endDate.Date > DateTime.UtcNow.Date)
        throw new ArgumentOutOfRangeException("The end date is greater than today.");

    var candles = _client.Spot.Market.GetKlines(symbol, interval, startTime: startDate, endTime: endDate, limit: 200).Data.ToList();

    while (endDate > candles.Last().OpenTime)
    {
        var moreCandles = _client.Spot.Market.GetKlines(symbol, interval, startTime: candles.Last().OpenTime, endTime: endDate, limit: 1000).Data.ToList();
        candles.AddRange(moreCandles.ExceptUsingJsonCompare(candles));
    }

    return candles.Cast<BinanceSpotKline>().ToList();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM