C#中使用Newtonsoft.Json为Address类实现自定义JSON反序列化(无需为User类编写自定义解析器)
当然可以实现!你完全不需要为User类编写自定义解析器,只需要给Address类单独配置自定义反序列化逻辑就好,正好符合你想要的基于JToken处理的方式。下面是具体的实现步骤和代码示例:
实现方案
首先,先修正你实体类里的几个小问题(不然默认反序列化会出问题):
- 你的
Adress类拼写错误,应该是Address - 类的字段默认是private,Newtonsoft.Json默认无法访问,需要改成public,或者加上
[JsonProperty]特性 - 注意
long是C#的关键字,建议把字段名改成Lon或者Longitude避免冲突
修正后的实体类:
public class User { public string Name { get; set; } public string Description { get; set; } public Address Address { get; set; } } public class Address { public double Lat { get; set; } public double Lon { get; set; } // 避免用long关键字 }
步骤1:编写接收JToken的Address反序列化方法
按照你的要求,先实现那个接收JToken返回Address的方法,这里模拟根据城市和国家获取坐标的自定义逻辑(你可以替换成自己的真实逻辑):
public static Address DeserializeAddress(JToken jtoken) { // 从JToken里提取JSON中的city和country字段 var city = jtoken["city"]?.ToString(); var country = jtoken["country"]?.ToString(); // 这里是你的自定义逻辑:根据城市和国家生成Lat和Lon // 示例逻辑,实际可以调用地理API或者本地映射表 var address = new Address(); if (city == "Paris" && country == "France") { address.Lat = 48.8566; address.Lon = 2.3522; } // 其他城市的逻辑可以继续添加 return address; }
步骤2:创建自定义JsonConverter
接下来,创建一个继承自JsonConverter<Address>的转换器,在ReadJson方法里调用上面的自定义方法:
public class AddressConverter : JsonConverter<Address> { public override Address ReadJson(JsonReader reader, Type objectType, Address existingValue, bool hasExistingValue, JsonSerializer serializer) { // 将JsonReader转换成JToken,方便处理 JToken jtoken = JToken.Load(reader); // 调用你定义的反序列化方法 return DeserializeAddress(jtoken); } // WriteJson方法如果不需要自定义序列化可以返回默认实现 public override void WriteJson(JsonWriter writer, Address value, JsonSerializer serializer) { // 如果你需要自定义Address的序列化逻辑,可以在这里实现 // 示例:序列化时输出city和country(如果有对应的字段的话),或者默认序列化Lat和Lon serializer.Serialize(writer, value); } }
步骤3:给Address类绑定转换器
有两种方式可以绑定这个转换器:
方式1:用特性标注Address类
直接在Address类上加上[JsonConverter]特性,这样每次反序列化Address时都会自动使用这个转换器:
[JsonConverter(typeof(AddressConverter))] public class Address { public double Lat { get; set; } public double Lon { get; set; } }
方式2:在序列化设置中添加转换器
如果不想修改Address类的代码,可以在调用JsonConvert.DeserializeObject时传入JsonSerializerSettings:
var settings = new JsonSerializerSettings(); settings.Converters.Add(new AddressConverter()); var json = "{ \"Name\" : \"TestUser\", \"Description\": \"Testing\", \"Address\": { \"city\": \"Paris\", \"country\": \"France\" } }"; User user = JsonConvert.DeserializeObject<User>(json, settings);
测试验证
运行上面的代码,反序列化后的user.Address.Lat会是48.8566,user.Address.Lon会是2.3522,完全符合你的自定义逻辑,而且不需要对User类做任何额外的反序列化配置。
这样就完美实现了你的需求:只针对Address类做自定义反序列化,User类用默认的反序列化逻辑即可。
内容的提问来源于stack exchange,提问作者Mahima gupta
相关产品推荐
相关产品推荐

