JSON反序列化报错:无法将JSON数组转为OrderBookElement类型
看起来你遇到的核心问题是JSON结构和C#类的映射不匹配:你的JSON里bids和asks的每一项都是一个JSON数组(比如["392031.00000000", "0.00254444"]),但你定义的OrderBookElement是一个C#类,JSON.NET默认会把类对应成JSON对象(键值对形式,比如{"price": 123, "volume": 456}),所以才会抛出那个类型不匹配的错误。
另外还要注意:你代码里OrderBookResponse的bids和asks属性是私有的(默认访问修饰符),JSON.NET默认无法反序列化私有属性,得改成public才行。
下面给你两种实用的解决方案:
方案一:用ValueTuple快速实现(最简单)
如果不需要自定义类的额外逻辑,直接用C#的ValueTuple可以省去定义OrderBookElement的麻烦,JSON.NET会自动把长度为2的数组映射到ValueTuple的两个元素:
public class OrderBookResponse { [JsonProperty("bids")] public List<(double Price, double Volume)> Bids { get; set; } [JsonProperty("asks")] public List<(double Price, double Volume)> Asks { get; set; } }
之后你的反序列化代码完全不用改:
var ordBook = JsonConvert.DeserializeObject<OrderBookResponse>(jsonResponse);
使用的时候直接通过ordBook.Bids[0].Price和ordBook.Bids[0].Volume访问即可,非常直观。
方案二:给自定义类添加数组反序列化支持
如果你还是想用OrderBookElement类,可以通过添加带参数的构造函数或者自定义转换器来实现:
方法A:用JsonConstructor标记构造函数
给OrderBookElement添加一个接收double[]的构造函数,并用[JsonConstructor]标记,让JSON.NET知道用这个构造函数来创建实例:
public class OrderBookElement { public double Price { get; set; } public double Volume { get; set; } // 用于JSON反序列化的构造函数 [JsonConstructor] public OrderBookElement(double[] values) { if (values?.Length >= 2) { Price = values[0]; Volume = values[1]; } } // 无参构造函数(如果需要序列化回去或者其他场景用到) public OrderBookElement() {} } public class OrderBookResponse { [JsonProperty("bids")] public List<OrderBookElement> Bids { get; set; } [JsonProperty("asks")] public List<OrderBookElement> Asks { get; set; } }
方法B:自定义JsonConverter
如果需要更灵活的控制(比如处理异常情况、自定义序列化逻辑),可以写一个转换器:
public class OrderBookElementConverter : JsonConverter<OrderBookElement> { public override OrderBookElement ReadJson(JsonReader reader, Type objectType, OrderBookElement existingValue, bool hasExistingValue, JsonSerializer serializer) { // 把JSON数组反序列化为double数组 var array = serializer.Deserialize<double[]>(reader); if (array == null || array.Length < 2) return null; return new OrderBookElement { Price = array[0], Volume = array[1] }; } // 如果需要把类序列回JSON数组,实现这个方法 public override void WriteJson(JsonWriter writer, OrderBookElement value, JsonSerializer serializer) { writer.WriteStartArray(); writer.WriteValue(value.Price); writer.WriteValue(value.Volume); writer.WriteEndArray(); } } // 给OrderBookElement标记使用这个转换器 [JsonConverter(typeof(OrderBookElementConverter))] public class OrderBookElement { public double Price { get; set; } public double Volume { get; set; } } public class OrderBookResponse { [JsonProperty("bids")] public List<OrderBookElement> Bids { get; set; } [JsonProperty("asks")] public List<OrderBookElement> Asks { get; set; } }
这样修改后,你的反序列化代码就能正常工作了。
内容的提问来源于stack exchange,提问作者someone_ smiley

