【问题标题】:Unable to deserialize JSON data into a List<T>无法将 JSON 数据反序列化为 List<T>
【发布时间】:2020-09-09 16:51:00
【问题描述】:

如果candles.json不存在或存在且第一个元素的开始日期和最后一个元素的结束日期不同,则将数据序列化为List&lt;IBinanceKline&gt;并创建candles .json。如果 candles.json 存在,它应该读取它并将数据反序列化为List&lt;IBinanceKline&gt;。目前,它只能DeserializeObject&lt;List&lt;IBinanceKline&gt;&gt; 出现以下错误消息:

Newtonsoft.Json.JsonSerializationException: '无法将当前 JSON 数组(例如 [1,2,3])反序列化为类型 'Binance.Net.Interfaces.IBinanceKline',因为该类型需要 JSON 对象(例如 {"name" :"value"}) 正确反序列化。 要修复此错误,请将 JSON 更改为 JSON 对象(例如 {"name":"value"})或将反序列化类型更改为数组或实现集合接口的类型(例如 ICollection、IList),例如可以从 JSON 数组反序列化。 JsonArrayAttribute 也可以添加到类型中以强制它从 JSON 数组反序列化。 路径“[0]”,第 1 行,位置 2。'

有趣的是,代码在更新库之前可以正常工作,现在它使用 IBinanceKline 而不是 BinanceKline。

candles.json 看起来像这样:

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

【问题讨论】:

  • 您的 JSON 是 List&lt;List&lt;something&gt;&gt;,而不是 List&lt;something&gt;,这基本上正是您的错误消息告诉您的内容。
  • @oerkelens,实际上它说GetCandlesByStartDateEndDate 返回List&lt;BinanceSpotKline&gt;
  • 它会反序列化为接口列表吗?我觉得需要一个具体的类来反序列化
  • 我不是在谈论您的代码,而是在谈论您的 JSON。它以[[ 开头并以]] 结尾,这使它成为一个数组数组或List&lt;List&lt;something&gt;&gt;。这永远不会反序列化为List&lt;something&gt;
  • @oerkelens,事实上,它曾经。我知道问题出在哪里。当我对其进行序列化时,它会将其序列化为List&lt;BinanceSpotKline&gt;,同时它试图将其反序列化为List&lt;IBinanceKline&gt;。 BinanceSpotKline 有一个额外的属性。

标签: c# json json-deserialization


【解决方案1】:

感谢您的 cmets,出现问题是因为 List&lt;IBinanceKline&gt; 并没有真正指定它将序列化到哪个类。事实上,它确实序列化为List&lt;BinanceSpotKline&gt;

解决方案:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-08
    • 1970-01-01
    • 2021-10-11
    相关资源
    最近更新 更多