如何使用Text.Json源生成器定义匹配双层嵌套JSON的数据模型
正确的数据模型及反序列化实现
你的JSON根结构是双层数组:第一层数组包含一个元素,该元素又是一个数组,数组内的每个元素是「键为订单ID、值为订单详情」的字典。原模型的问题在于类型完全不匹配:你试图将双层数组反序列化为单个OpenOrder对象,且OpenOrder类的OrderFrame属性属于多余的嵌套结构,和JSON的实际层级不对应。
正确实现步骤
调整数据模型
去掉多余的OpenOrder类,直接用Dictionary<string, OpenOrderFrame>作为内层元素类型,外层匹配双层数组/列表结构:public class OpenOrderFrame { public string fee { get; set; } public string cost { get; set; } public string vol_exec { get; set; } public string avg_price { get; set; } } // 配置源生成器,指定目标类型为双层列表 [JsonSerializable(typeof(List<List<Dictionary<string, OpenOrderFrame>>>), GenerationMode = JsonSourceGenerationMode.Default)] public partial class MyContext : JsonSerializerContext { }正确执行反序列化
调用Deserialize时传入对应类型的上下文:var json = @"[[{""OU2CJ3-UBRYG-KCPVS5"":{""cost"":""27187.08000"",""vol_exec"":""3.40000000"",""fee"":""27.18708"",""avg_price"":""7996.20000""}}]]"; var result = JsonSerializer.Deserialize(json, MyContext.Default.ListListDictionaryStringOpenOrderFrame); // 示例:访问解析后的数据 if (result?.Count > 0 && result[0].Count > 0) { var orderDict = result[0][0]; foreach (var (orderId, frame) in orderDict) { Console.WriteLine($"订单ID:{orderId}"); Console.WriteLine($"成本:{frame.cost}"); Console.WriteLine($"成交量:{frame.vol_exec}"); } }
可选:用双层数组替代列表
如果偏好数组类型,可将源生成器的目标类型改为Dictionary<string, OpenOrderFrame>[][]:
[JsonSerializable(typeof(Dictionary<string, OpenOrderFrame>[][]), GenerationMode = JsonSourceGenerationMode.Default)] public partial class MyContext : JsonSerializerContext { } // 反序列化调用: var result = JsonSerializer.Deserialize(json, MyContext.Default.DictionaryStringOpenOrderFrameArrayArray);
问题根源说明
- 原代码中
OpenOrder类的OrderFrame属性,会让序列化器期望JSON结构是{"OrderFrame": {...}},但实际JSON没有这个嵌套层级,直接是字典对象。 - JSON的根是双层数组而非单个对象,必须用对应的集合类型(列表/数组)匹配,否则序列化器无法解析,返回
null。
内容的提问来源于stack exchange,提问作者Guillaume Paris
相关产品推荐
相关产品推荐

