如何访问动态反序列化后嵌套JSON对象的随机子条目?
如何访问带有动态随机ID的JSON子条目?
你提到用Newtonsoft.Json的JsonConvert.DeserializeObject把JSON字符串转成dynamic后,能顺利访问entry1、entry2这些一级条目,但因为子条目的ID(比如49208118)是随机变化的,没法通过conversionResult.entry1.49208118.name这种硬编码的方式访问,对吧?
先贴一下你给出的测试JSON和初始化代码:
var testJson = @"{'entry1': { '49208118': { 'name': 'just a name' } }, 'entry2': { '49208118': [ { 'description': 'just a description' }, { 'description': 'another description' } ] } }"; dynamic conversionResult = JsonConvert.DeserializeObject(testJson);
接下来给你几个实用的解决办法:
方法1:把动态对象转成字典处理
因为dynamic在这里本质是ExpandoObject,可以直接转成Dictionary<string, object>,这样就能遍历键值对,拿到那个随机ID对应的内容:
处理entry1(单个对象)
// 把entry1转成字典 var entry1Dict = conversionResult.entry1 as Dictionary<string, object>; // 取第一个键值对(因为entry1下只有一个动态ID条目) var entry1Item = entry1Dict.First(); string randomId = entry1Item.Key; // 这里拿到随机的49208118 // 再把值转成动态对象或者字典,获取name dynamic entry1Content = entry1Item.Value; Console.WriteLine(entry1Content.name); // 输出"just a name"
处理entry2(数组类型)
entry2下的动态ID对应是数组,处理逻辑类似:
var entry2Dict = conversionResult.entry2 as Dictionary<string, object>; var entry2Item = entry2Dict.First(); dynamic entry2Array = entry2Item.Value; // 遍历数组里的description foreach (var item in entry2Array) { Console.WriteLine(item.description); }
方法2:直接用JObject解析(更灵活)
如果你不想用dynamic,可以用Newtonsoft.Json的JObject来解析,它本身就支持遍历键值对,而且类型更明确:
JObject jObj = JObject.Parse(testJson); // 处理entry1 JToken entry1 = jObj["entry1"]; // 获取entry1下的第一个子节点(随机ID对应的节点) JToken entry1Content = entry1.Children().First().First; Console.WriteLine(entry1Content["name"].Value<string>()); // 处理entry2 JToken entry2 = jObj["entry2"]; JArray entry2Array = entry2.Children().First().First as JArray; foreach (JToken item in entry2Array) { Console.WriteLine(item["description"].Value<string>()); }
方法3:用强类型配合字典(如果结构固定,只是ID动态)
如果API返回的结构除了那个随机ID外都是固定的,还可以定义强类型,把动态ID的部分用字典来承载:
// 定义强类型 public class Entry1Content { public string name { get; set; } } public class Entry2Item { public string description { get; set; } } public class ApiResponse { public Dictionary<string, Entry1Content> entry1 { get; set; } public Dictionary<string, List<Entry2Item>> entry2 { get; set; } } // 反序列化到强类型 var response = JsonConvert.DeserializeObject<ApiResponse>(testJson); // 访问entry1的内容 var entry1Content = response.entry1.Values.First(); Console.WriteLine(entry1Content.name); // 访问entry2的内容 var entry2List = response.entry2.Values.First(); foreach (var item in entry2List) { Console.WriteLine(item.description); }
这几种方法里,强类型字典的方式最安全,能在编译期就检查类型;JObject的方式最灵活,适合结构多变的场景;而转字典的方法则是在dynamic基础上的延伸,适合快速处理。
内容的提问来源于stack exchange,提问作者Oblomov
相关产品推荐
相关产品推荐

