如何配置Text.Json源生成器参数以反序列化复杂JSON字符串
问题分析与解决方案
首先,你的JSON字符串是一个混合类型的数组,包含三个元素:
- 一个嵌套数组,里面的每个元素是「订单ID为键,订单详情为值」的对象
- 字符串
"openOrders" - 包含
sequence字段的对象
你之前的错误在于把整个JSON当成了OpenOrderFrame[]类型的数组,但实际结构完全不匹配,导致反序列化失败。以下是两种正确的实现方式:
方式一:自定义转换器实现强类型映射(推荐)
1. 定义模型类
// 订单详情模型,属性名与JSON字段一一对应 public class OpenOrder { public string Cost { get; set; } public string Vol_exec { get; set; } public string Fee { get; set; } public string Avg_price { get; set; } } // 序列号信息模型 public class SequenceData { public int Sequence { get; set; } } // 最终的响应模型,对应JSON数组的三个元素 public class OpenOrderResponse { public Dictionary<string, OpenOrder>[] Orders { get; set; } public string ChannelName { get; set; } public SequenceData SequenceInfo { get; set; } }
2. 编写自定义转换器
将JSON数组转换为OpenOrderResponse对象:
public class OpenOrderResponseConverter : JsonConverter<OpenOrderResponse> { public override OpenOrderResponse Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType != JsonTokenType.StartArray) throw new JsonException("JSON结构应为数组"); // 读取第一个元素:订单数组 reader.Read(); var orders = JsonSerializer.Deserialize<Dictionary<string, OpenOrder>[]>(ref reader, options); // 读取第二个元素:频道名称字符串 reader.Read(); var channelName = reader.GetString(); // 读取第三个元素:序列号对象 reader.Read(); var sequenceInfo = JsonSerializer.Deserialize<SequenceData>(ref reader, options); // 确认数组结束 reader.Read(); if (reader.TokenType != JsonTokenType.EndArray) throw new JsonException("JSON数组未正常结束"); return new OpenOrderResponse { Orders = orders, ChannelName = channelName, SequenceInfo = sequenceInfo }; } public override void Write(Utf8JsonWriter writer, OpenOrderResponse value, JsonSerializerOptions options) { writer.WriteStartArray(); JsonSerializer.Serialize(writer, value.Orders, options); writer.WriteStringValue(value.ChannelName); JsonSerializer.Serialize(writer, value.SequenceInfo, options); writer.WriteEndArray(); } }
3. 配置源生成器上下文
[JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)] [JsonSerializable(typeof(OpenOrderResponse))] [JsonSerializable(typeof(Dictionary<string, OpenOrder>[]))] [JsonSerializable(typeof(SequenceData))] public partial class OpenOrderContext : JsonSerializerContext { static OpenOrderContext() { // 注册自定义转换器 Default.Converters.Add(new OpenOrderResponseConverter()); } }
4. 反序列化代码
var json = @"[[{""OU2CJ3-UBRYG-KCPVS1"":{""cost"":""27187.08000"",""vol_exec"":""3.60000000"",""fee"":""27.18708"",""avg_price"":""7996.20000""}}],""openOrders"",{""sequence"": 59342}]"; var response = JsonSerializer.Deserialize(json, OpenOrderContext.Default.OpenOrderResponse);
方式二:直接处理object数组(快速实现)
如果不需要强类型模型,可以直接反序列化为object[],再手动转换每个元素:
1. 配置源生成器上下文
[JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)] [JsonSerializable(typeof(object[]))] [JsonSerializable(typeof(Dictionary<string, OpenOrder>[]))] [JsonSerializable(typeof(SequenceData))] public partial class OpenOrderContext : JsonSerializerContext { }
2. 反序列化与转换
var json = @"[[{""OU2CJ3-UBRYG-KCPVS1"":{""cost"":""27187.08000"",""vol_exec"":""3.60000000"",""fee"":""27.18708"",""avg_price"":""7996.20000""}}],""openOrders"",{""sequence"": 59342}]"; // 先反序列化为object数组 var rawArray = JsonSerializer.Deserialize<object[]>(json, OpenOrderContext.Default.ObjectArray); // 逐个转换元素 var orders = JsonSerializer.Deserialize<Dictionary<string, OpenOrder>[]>( JsonSerializer.Serialize(rawArray[0]), OpenOrderContext.Default.DictionaryStringOpenOrderArray); string channelName = (string)rawArray[1]; var sequenceInfo = JsonSerializer.Deserialize<SequenceData>( JsonSerializer.Serialize(rawArray[2]), OpenOrderContext.Default.SequenceData);
内容的提问来源于stack exchange,提问作者Guillaume Paris
相关产品推荐
相关产品推荐

