Binance API JSON反序列化报错:无法解析bids末尾空数组
解决Binance API深度数据反序列化异常问题
我来帮你搞定这个反序列化的问题!你遇到的异常,核心原因是Binance返回的每个bid项是一个包含三个元素的数组,前两个是字符串(价格和数量),第三个是空数组[],但你定义的string[][]模型期望每个子数组的元素都是字符串,这就导致类型不匹配,反序列化失败。
问题分析
先看Binance返回的bids结构:
"bids": [ ["0.09766700","12.64700000",[]], ["0.09766600","0.19500000",[]] ]
每个bid是一个三元数组:
- 第一个元素:价格(字符串类型)
- 第二个元素:数量(字符串类型)
- 第三个元素:空数组(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
相关产品推荐
相关产品推荐

