如何将含无命名对象集合的JSON反序列化为C#类?
处理动态键JSON的C#反序列化方案
嘿,我之前也碰到过这种带动态数字键的JSON格式,确实有点绕,不过咱们一步步拆解就能搞定!先明确你给的JSON核心特点:外层是动态字符串键(比如示例里的"32"),每个键对应一个包含name和data的对象;而data里的每个属性(比如supported、version)都遵循完全一致的结构,咱们可以用C#的字典适配动态键,再配合强类型类固定重复结构。
第一步:定义对应C#类
先把重复出现的属性结构抽成通用类,再逐层往上定义:
1. 通用属性值类(适配data下的统一结构)
public class GenericPropertyValue { public object Value { get; set; } public string Type { get; set; } public long InvalidateTime { get; set; } public long UpdateTime { get; set; } }
2. 单个计划对象类(对应每个数字键的值)
public class Plan { // 用Newtonsoft.Json的话用[JsonProperty],用System.Text.Json就换[JsonPropertyName] [JsonProperty("name")] public string Name { get; set; } [JsonProperty("data")] // 用字典适配data下的动态属性键 public Dictionary<string, GenericPropertyValue> Data { get; set; } }
3. 最外层根对象(适配动态数字键)
直接继承字典就能完美匹配外层的动态键结构:
public class RootObject : Dictionary<string, Plan> { // 无需额外属性,继承字典即可直接反序列化外层动态键 }
第二步:反序列化代码示例
用Newtonsoft.Json(Json.NET,最常用第三方库)
// 补全后的示例JSON字符串 string json = @"{""32"": { ""name"": ""Basic"", ""data"": { ""value"": null, ""type"": ""empty"", ""supported"": { ""value"": true, ""type"": ""bool"", ""invalidateTime"": 1520421448, ""updateTime"": 1520421449 }, ""version"": { ""value"": 1, ""type"": ""int"", ""invalidateTime"": 1520421448, ""updateTime"": 1520421449 }, ""security"": { ""value"": false, ""type"": ""bool"", ""invalidateTime"": 1520421448, ""updateTime"": 1520421449 } } } }"; // 反序列化 var result = JsonConvert.DeserializeObject<RootObject>(json); // 访问示例 string basicPlanName = result["32"].Name; bool isSupported = (bool)result["32"].Data["supported"].Value; int planVersion = (int)result["32"].Data["version"].Value;
用System.Text.Json(.NET Core/.NET 5+内置库)
先调整类的特性为内置库的标注:
public class GenericPropertyValue { [JsonPropertyName("value")] public object Value { get; set; } [JsonPropertyName("type")] public string Type { get; set; } [JsonPropertyName("invalidateTime")] public long InvalidateTime { get; set; } [JsonPropertyName("updateTime")] public long UpdateTime { get; set; } } public class Plan { [JsonPropertyName("name")] public string Name { get; set; } [JsonPropertyName("data")] public Dictionary<string, GenericPropertyValue> Data { get; set; } }
然后执行反序列化:
var result = JsonSerializer.Deserialize<Dictionary<string, Plan>>(json); // 访问方式和上面完全一致 string basicPlanName = result["32"].Name;
额外优化:安全转换Value类型
因为Value的类型是动态的(null、bool、int等),可以根据Type字段做安全转换:
var securityProp = result["32"].Data["security"]; if (securityProp.Type == "bool" && securityProp.Value is bool securityValue) { // 安全使用securityValue } else if (securityProp.Type == "int" && securityProp.Value is int intValue) { // 安全使用intValue }
内容的提问来源于stack exchange,提问作者Rakker
相关产品推荐
相关产品推荐

