如何将含动态键的JSON转换为C#字典或动态对象?
解决动态键JSON反序列化为字典的问题
你的JSON结构核心是外层包含results数组,数组内的对象拥有content1到contentn这类动态键,每个键对应固定结构的子对象。要避免创建大量实体类,关键是正确映射层级结构,以下是两种主流JSON库的实现方案:
一、Newtonsoft.Json(JsonConvert)方案
1. 结合自定义子对象类 + 字典
如果子对象的prop1、prop2结构固定,可以定义一个简单类来映射,外层用字典承载动态键:
// 定义子对象的结构类 public class ContentProps { public string Prop1 { get; set; } public string Prop2 { get; set; } } // 定义API返回的外层结构类 public class ApiResponse { public List<Dictionary<string, ContentProps>> Results { get; set; } } // 反序列化操作 string json = "你的API返回JSON字符串"; var response = JsonConvert.DeserializeObject<ApiResponse>(json); // 访问数据示例 if (response.Results?.Count > 0) { var firstResult = response.Results[0]; foreach (var contentEntry in firstResult) { Console.WriteLine($"动态键:{contentEntry.Key}"); Console.WriteLine($"Prop1值:{contentEntry.Value.Prop1}"); Console.WriteLine($"Prop2值:{contentEntry.Value.Prop2}"); } }
2. 全嵌套字典(无需定义类)
如果不想定义任何实体类,直接用嵌套字典映射整个结构:
public class ApiResponse { public List<Dictionary<string, Dictionary<string, string>>> Results { get; set; } } // 反序列化与访问 var response = JsonConvert.DeserializeObject<ApiResponse>(json); if (response.Results?.Count > 0) { var firstResult = response.Results[0]; foreach (var contentEntry in firstResult) { var props = contentEntry.Value; Console.WriteLine($"动态键:{contentEntry.Key}"); Console.WriteLine($"Prop1值:{props["prop1"]}"); Console.WriteLine($"Prop2值:{props["prop2"]}"); } }
3. 动态解析(无需外层类)
如果连外层类都不想定义,可直接用JObject解析:
var jObj = JObject.Parse(json); var results = jObj["results"].ToObject<List<Dictionary<string, ContentProps>>>(); // 或嵌套字典版本 // var results = jObj["results"].ToObject<List<Dictionary<string, Dictionary<string, string>>>>();
二、System.Text.Json(JsonSerializer)方案
1. 结合自定义子对象类 + 字典
注意需要用JsonPropertyName匹配JSON的小写键,或开启大小写不敏感:
public class ContentProps { [JsonPropertyName("prop1")] public string Prop1 { get; set; } [JsonPropertyName("prop2")] public string Prop2 { get; set; } } public class ApiResponse { [JsonPropertyName("results")] public List<Dictionary<string, ContentProps>> Results { get; set; } } // 反序列化操作 var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; var response = JsonSerializer.Deserialize<ApiResponse>(json, options); // 访问方式与Newtonsoft版本一致
2. 全嵌套字典(无需定义类)
public class ApiResponse { [JsonPropertyName("results")] public List<Dictionary<string, Dictionary<string, string>>> Results { get; set; } } var response = JsonSerializer.Deserialize<ApiResponse>(json, options);
3. 动态解析(无需外层类)
用JsonDocument直接解析指定节点:
using var doc = JsonDocument.Parse(json); var resultsElement = doc.RootElement.GetProperty("results"); var results = JsonSerializer.Deserialize<List<Dictionary<string, ContentProps>>>(resultsElement, options);
常见失败原因
你之前尝试失败大概率是层级映射错误:
- 直接将整个JSON反序列化为
Dictionary,忽略了外层的results数组结构 - 未将数组内的对象映射为
Dictionary<string, T>,而是错误用了List
内容的提问来源于stack exchange,提问作者Gazi Këpuska
相关产品推荐
相关产品推荐

