You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Binance API JSON反序列化报错:无法解析bids末尾空数组

解决Binance API深度数据反序列化异常问题

我来帮你搞定这个反序列化的问题!你遇到的异常,核心原因是Binance返回的每个bid项是一个包含三个元素的数组,前两个是字符串(价格和数量),第三个是空数组[],但你定义的string[][]模型期望每个子数组的元素都是字符串,这就导致类型不匹配,反序列化失败。

问题分析

先看Binance返回的bids结构:

"bids": [ 
  ["0.09766700","12.64700000",[]], 
  ["0.09766600","0.19500000",[]]
]

每个bid是一个三元数组:

  1. 第一个元素:价格(字符串类型)
  2. 第二个元素:数量(字符串类型)
  3. 第三个元素:空数组(Binance保留字段,无实际数据)

你之前用string[][]时,反序列化器会尝试把第三个元素(空数组)转换成字符串,这显然行不通;换成float类型同理,空数组无法转成数值,所以都会抛出异常。

解决方案

这里提供两种实用的解决方式,你可以根据需求选择:

方案1:用灵活类型接收后手动处理

这种方式简单直接,先用List<object[]>接收bids,再手动提取价格和数量:

// 定义匹配API结构的模型
public class BinanceDepthResponse
{
    [JsonPropertyName("lastUpdateId")]
    public long LastUpdateId { get; set; }

    [JsonPropertyName("bids")]
    public List<object[]> Bids { get; set; }
}

// 反序列化并处理数据
var jsonString = "你的API返回的JSON字符串";
var depthData = JsonSerializer.Deserialize<BinanceDepthResponse>(jsonString);

// 遍历处理每个bid
foreach (var bid in depthData.Bids)
{
    // 把字符串转成decimal(推荐用decimal处理金融数据,避免浮点数精度问题)
    var price = decimal.Parse(bid[0].ToString());
    var quantity = decimal.Parse(bid[1].ToString());
    // bid[2]是空数组,直接忽略即可
    Console.WriteLine($"价格:{price},数量:{quantity}");
}

方案2:自定义JSON转换器实现强类型映射

如果想要更优雅的强类型处理,可以自定义一个JsonConverter,把数组形式的bid项直接映射到实体类:

// 定义bid实体类
public class BinanceOrderBookEntry
{
    public decimal Price { get; set; }
    public decimal Quantity { get; set; }
}

// 自定义转换器
public class BinanceOrderBookEntryConverter : JsonConverter<BinanceOrderBookEntry>
{
    public override BinanceOrderBookEntry Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        // 验证是否是数组开头
        if (reader.TokenType != JsonTokenType.StartArray)
            throw new JsonException("预期数组格式的订单簿条目");

        // 读取价格
        reader.Read();
        var price = decimal.Parse(reader.GetString());

        // 读取数量
        reader.Read();
        var quantity = decimal.Parse(reader.GetString());

        // 跳过第三个空数组
        reader.Read();
        if (reader.TokenType == JsonTokenType.StartArray)
            reader.Read(); // 跳过空数组的结束标记

        // 跳过当前bid数组的结束标记
        reader.Read();

        return new BinanceOrderBookEntry { Price = price, Quantity = quantity };
    }

    // 如果需要序列化回JSON,可实现Write方法(可选)
    public override void Write(Utf8JsonWriter writer, BinanceOrderBookEntry value, JsonSerializerOptions options)
    {
        writer.WriteStartArray();
        writer.WriteStringValue(value.Price.ToString());
        writer.WriteStringValue(value.Quantity.ToString());
        writer.WriteStartArray();
        writer.WriteEndArray();
        writer.WriteEndArray();
    }
}

// 定义顶层响应模型
public class BinanceDepthResponse
{
    [JsonPropertyName("lastUpdateId")]
    public long LastUpdateId { get; set; }

    [JsonPropertyName("bids")]
    [JsonConverter(typeof(BinanceOrderBookEntryConverter))]
    public List<BinanceOrderBookEntry> Bids { get; set; }
}

// 使用方式
var jsonString = "你的API返回的JSON字符串";
var options = new JsonSerializerOptions();
var depthData = JsonSerializer.Deserialize<BinanceDepthResponse>(jsonString, options);

// 直接访问强类型数据
foreach (var bid in depthData.Bids)
{
    Console.WriteLine($"价格:{bid.Price},数量:{bid.Quantity}");
}

额外提示

处理金融数据时,强烈推荐用decimal类型代替float/double,因为浮点数会存在精度丢失问题,而decimal能精准表示货币类数值。

内容的提问来源于stack exchange,提问作者Yarden Weiss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:32:24