如何用Newtonsoft.JSON反序列化非数组型多对象JSON结构?
如何用Newtonsoft.Json反序列化键值对结构的Users数据
这个问题很常见,其实只要利用Newtonsoft.Json对字典结构的原生支持就能轻松解决,不用绕弯子靠索引取字段。下面给你一步步拆解实现方式:
1. 定义对应的实体类
首先我们需要把JSON的层级结构映射成C#类,核心是把users字段定义成Dictionary<TKey, User>类型——因为JSON里的users本质是动态键值对集合,正好对应C#的字典类型。
// 单个用户的实体类,对应JSON里的用户对象 public class User { public int Id { get; set; } public string Name { get; set; } } // 对应JSON里的_embedded节点 public class EmbeddedData { // 这里用Dictionary<string, User>是因为JSON里的键是字符串格式的数字 // 如果确定键是整数,也可以用Dictionary<int, User>,Newtonsoft会自动完成类型转换 public Dictionary<string, User> Users { get; set; } } // 最外层的根对象类 public class RootResponse { // 用JsonProperty特性指定JSON里的字段名"_embedded",避免类名不符合C#命名规范的问题 [JsonProperty("_embedded")] public EmbeddedData Embedded { get; set; } }
2. 执行反序列化操作
有了实体类之后,反序列化就和普通对象完全一样了,之后你可以像操作常规对象/字典一样访问所有用户数据,完全不需要用索引:
// 你的原始JSON字符串 string json = @"{""_embedded"": { ""users"": { ""1688416"": { ""id"": 1688416, ""name"": ""test"" }, ""1688395"": { ""id"": 1688395, ""name"": ""test"" }, ""1625614"": { ""id"": 1625614, ""name"": ""test"" } } } }"; // 反序列化到RootResponse对象 RootResponse response = JsonConvert.DeserializeObject<RootResponse>(json); // 遍历所有用户(像操作普通字典一样) foreach (var userEntry in response.Embedded.Users) { Console.WriteLine($"用户键: {userEntry.Key}, 用户ID: {userEntry.Value.Id}, 用户名: {userEntry.Value.Name}"); } // 根据键快速获取特定用户 if (response.Embedded.Users.TryGetValue("1688416", out User targetUser)) { Console.WriteLine($"找到目标用户:ID={targetUser.Id}, 姓名={targetUser.Name}"); }
额外小技巧:动态类型(不推荐但可用)
如果你不想定义实体类,也可以用动态类型来快速访问,但这种方式没有编译时检查,容易出错,仅适合临时调试场景:
dynamic dynamicResponse = JsonConvert.DeserializeObject(json); foreach (var userEntry in dynamicResponse._embedded.users) { Console.WriteLine($"用户键: {userEntry.Name}, 用户ID: {userEntry.Value.id}, 用户名: {userEntry.Value.name}"); }
总的来说,用静态实体类+字典的方式是最稳妥、最符合你需求的方案,既保留了静态类型的安全性,又能完美适配动态键值对的JSON结构。
内容的提问来源于stack exchange,提问作者Vasiliy Terkin
相关产品推荐
相关产品推荐

