如何将含动态名称的JSON字符串转换为C#对象?
解决JSON动态键名转C#类的问题
嘿,很高兴能帮你搞定这个JSON转C#类的难题!你遇到的核心问题是JSON里的result对象包含动态变化的键名(比如foo、bar,可能后续还会出现其他不确定的键),固定属性的类结构没法适配这种场景,所以我们需要用更灵活的方式来处理。
先看你提供的JSON结构:
{ "success": true, "result": { "foo": [ { "keys": "values" } ], "bar": [ { "keys": "values" } ] } }
注意到每个动态键对应的值都是同结构的对象数组,所以我们可以用Dictionary<string, List<T>>来容纳这些可变的键值对,下面是具体的解决方案:
方案一:直接用Dictionary简化结构
这种方式最适合result里全是动态键的场景,不需要单独定义Result类:
// 定义数组中单个对象的结构(所有动态键对应的数组元素结构一致) public class Item { public string keys { get; set; } } // 根对象类 public class RootObject { public bool success { get; set; } // result直接定义为字典,键是动态字符串,值是Item的列表 public Dictionary<string, List<Item>> result { get; set; } }
方案二:混合固定键与动态键(用JsonExtensionData)
如果result里除了动态键,还有一些固定不变的属性,可以用[JsonExtensionData]特性来捕获所有动态键,同时保留固定属性:
public class Item { public string keys { get; set; } } public class Result { // 假设这里有一个固定属性 public string FixedProperty { get; set; } // 捕获所有动态键值对,JToken可以转换为对应的类型 [Newtonsoft.Json.JsonExtensionData] public Dictionary<string, Newtonsoft.Json.Linq.JToken> DynamicProperties { get; set; } } public class RootObject { public bool success { get; set; } public Result result { get; set; } }
反序列化示例(以Newtonsoft.Json为例)
不管用哪种方案,反序列化的逻辑都很简单:
string json = "{ \"success\": true, \"result\": { \"foo\": [ { \"keys\": \"values\" } ], \"bar\": [ { \"keys\": \"values\" } ] } }"; var root = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(json); // 遍历动态键值对 foreach (var kvp in root.result) { Console.WriteLine($"动态键名:{kvp.Key}"); foreach (var item in kvp.Value) { Console.WriteLine($"Item的keys值:{item.keys}"); } }
为什么原来的结构不行?
你之前写的固定属性类(Result里定义foo、bar)只能适配已知的键,一旦JSON里出现新的键(比如baz),反序列化时这些新键会被忽略(或报错,取决于序列化配置),而用Dictionary可以自动适配所有动态键,完全不用修改类结构。
内容的提问来源于stack exchange,提问作者Kapein
相关产品推荐
相关产品推荐

