无唯一属性名的JSON反序列化:C#对象转换问题
解决JSON反序列化为C# Dictionary的问题
你遇到的核心问题是JSON结构和你定义的C#类不匹配:你的JSON顶层就是一个string键对应Item值的字典结构,但你定义的Response类却把这个字典包装在了Objects属性里——而你的JSON中根本不存在Objects这个字段,导致反序列化时无法正确映射数据。
下面给你两种可行的解决方案:
方案1:直接反序列化为Dictionary<string, Item>(最简洁推荐)
既然你的JSON本身就是标准的字典格式,完全不需要额外的Response类,直接将JSON反序列化为Dictionary<string, Item>即可。
使用Newtonsoft.Json(Json.NET)的示例:
using Newtonsoft.Json; // 你的JSON字符串 string json = "{ \"1ST\": { \"name\": \"One\", \"symbol\": \"1st\" }, \"2ND\": { \"name\": \"Two\", \"symbol\": \"2nd\" } }"; // 直接反序列化为字典 Dictionary<string, Item> items = JsonConvert.DeserializeObject<Dictionary<string, Item>>(json); // 访问示例 Console.WriteLine(items["1ST"].name); // 输出 "One"
使用.NET内置System.Text.Json的示例:
using System.Text.Json; string json = "{ \"1ST\": { \"name\": \"One\", \"symbol\": \"1st\" }, \"2ND\": { \"name\": \"Two\", \"symbol\": \"2nd\" } }"; // 默认System.Text.Json大小写敏感,若需要匹配JSON的小写键,可配置选项 var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; Dictionary<string, Item> items = JsonSerializer.Deserialize<Dictionary<string, Item>>(json, options); // 访问示例 Console.WriteLine(items["2ND"].symbol); // 输出 "2nd"
方案2:保留Response类,通过调整结构适配
如果你因业务需求必须保留Response类,可以通过以下两种方式适配:
方式A:让Response继承自Dictionary<string, Item>
这样Response本身就具备字典的特性,直接对应JSON的顶层结构:
public class Response : Dictionary<string, Item> { } public class Item { public string name { get; set; } public string symbol { get; set; } } // 反序列化示例(以Newtonsoft.Json为例) Response response = JsonConvert.DeserializeObject<Response>(json); Console.WriteLine(response["1ST"].name); // 输出 "One"
方式B:使用序列化特性映射字段
如果不想继承字典,可以给Response的Objects属性添加特性,让它捕获JSON的所有顶层键值对(以Newtonsoft.Json为例):
using Newtonsoft.Json.Linq; public class Response { [JsonExtensionData] private Dictionary<string, JToken> _extensionData; // 手动转换为Item字典 public Dictionary<string, Item> Objects { get => _extensionData.ToDictionary(kv => kv.Key, kv => kv.Value.ToObject<Item>()); set => _extensionData = value.ToDictionary(kv => kv.Key, kv => JToken.FromObject(kv.Value)); } } // 反序列化后可直接访问Objects属性 Response response = JsonConvert.DeserializeObject<Response>(json); Console.WriteLine(response.Objects["2ND"].symbol); // 输出 "2nd"
另外补充一点:如果你的C#属性想遵循帕斯卡命名法(比如Name而非name),可以通过特性指定JSON键名,例如:
public class Item { [JsonProperty("name")] // Newtonsoft.Json // [JsonPropertyName("name")] // System.Text.Json public string Name { get; set; } [JsonProperty("symbol")] // [JsonPropertyName("symbol")] public string Symbol { get; set; } }
内容的提问来源于stack exchange,提问作者Justin
相关产品推荐
相关产品推荐

