如何使用Newtonsoft.JSON将JSON反序列化为带Name属性的List<House>
解决方案
方法1:自定义JsonConverter实现(通用性最高,适配类结构不固定的场景)
不需要修改现有类结构,直接通过自定义转换器实现外层JSON键到House类Name属性的映射,实现逻辑如下:
- 先编写自定义转换器类:
public class HouseConverter : JsonConverter<List<House>> { public override List<House> ReadJson(JsonReader reader, Type objectType, List<House> existingValue, bool hasExistingValue, JsonSerializer serializer) { var result = new List<House>(); var outerObj = JObject.Load(reader); // 遍历外层JSON的所有键值对 foreach (var jsonProperty in outerObj.Properties()) { // 把JSON键赋值给House的Name属性 var house = new House { Name = jsonProperty.Name }; // 反序列化对应数组的Person内容填充到House var personList = jsonProperty.Value.ToObject<List<Person>>(serializer); if (personList != null) { house.AddRange(personList); } result.Add(house); } return result; } // 如果不需要序列化回原JSON格式,这个方法可以不用实现 public override void WriteJson(JsonWriter writer, List<House> value, JsonSerializer serializer) { var jObj = new JObject(); foreach (var house in value) { jObj[house.Name] = JArray.FromObject(house, serializer); } jObj.WriteTo(writer); } }
- 反序列化时指定转换器即可直接得到目标结果:
var result = JsonConvert.DeserializeObject<List<House>>(你的JSON字符串, new HouseConverter());
方法2:中间字典转换(写法更简单,无需自定义Converter)
如果不想单独写转换器,可以用两步转换的方式实现:
// 第一步先反序列化为字典,键是房屋名,值是住户列表 var tempDict = JsonConvert.DeserializeObject<Dictionary<string, List<Person>>>(你的JSON字符串); // 第二步手动转换为List<House> var result = tempDict.Select(kv => { var house = new House { Name = kv.Key }; house.AddRange(kv.Value); return house; }).ToList();
注意:由于你的House类继承自
List<Person>,属于集合类型,Newtonsoft.JSON默认反序列化集合类型时会忽略类自身定义的额外属性,因此没有办法仅通过原生特性配置实现需求,必须用上面两种方式手动处理Name属性的赋值。如果后续类结构调整,只需要修改自定义Converter的映射逻辑即可,上层调用代码不需要改动。
内容的提问来源于stack exchange,提问作者popsicle7500
相关产品推荐
相关产品推荐

