如何用JsonConvert.DeserializeObject反序列化含动态对象名的JSON?
解决动态键JSON的反序列化问题
我之前对接第三方接口时也碰到过这种动态键的情况,不用纠结于生成固定类结构,这里有两种实用的解决方法:
方法一:用Dictionary<string, T>替代动态键部分
这种方法适合需要强类型处理的场景,我们可以把data节点下的动态键替换成Dictionary<string, List<DataItem>>,这样不管键是什么值,都能正常反序列化。
首先定义对应的类结构:
// 对应JSON里的all对象 public class All { public int f1 { get; set; } public int f2 { get; set; } public double f3 { get; set; } } // 对应动态键数组里的单个元素 public class DataItem { public All all { get; set; } } // 对应meta节点 public class Meta { public int count { get; set; } } // 根对象,用Dictionary接收动态键 public class RootResponse { public string status { get; set; } public Meta meta { get; set; } public Dictionary<string, List<DataItem>> data { get; set; } }
然后反序列化并处理数据:
var response = JsonConvert.DeserializeObject<RootResponse>(jsonString); // 遍历动态键(如果有多个的话) foreach (var entry in response.data) { string dynamicKey = entry.Key; // 这里就是示例中的"2000314370" List<DataItem> items = entry.Value; // 提取具体数据 var firstItemAll = items[0].all; Console.WriteLine($"f1: {firstItemAll.f1}, f2: {firstItemAll.f2}, f3: {firstItemAll.f3}"); }
方法二:用JObject动态解析
如果只是临时提取数据,不需要强类型,直接用JObject解析会更灵活:
var jObj = JObject.Parse(jsonString); // 获取data节点下的第一个动态键(如果有多个可以遍历Properties) var dataNode = jObj["data"]; var dynamicKey = dataNode.Properties().First().Name; // 提取all对象里的字段 var allNode = dataNode[dynamicKey][0]["all"]; int f1 = allNode["f1"].Value<int>(); int f2 = allNode["f2"].Value<int>(); double f3 = allNode["f3"].Value<double>();
总结
- 如果后续需要频繁操作这些数据,方法一的强类型方案更适合,代码可读性和维护性更好;
- 如果只是一次性提取少量数据,方法二的动态解析更轻便,不用定义一堆类。
内容的提问来源于stack exchange,提问作者Adrian K
相关产品推荐
相关产品推荐

