.NET Newtonsoft JSON如何将旧结构反序列化为新结构?
问题描述
原C#模型:
public class Person { public string Name {get;set;} public string Address {get;set;} public string City {get;set;} }
序列化后的JSON:
{"Name":"Test Person","Address":"12345 Main St","City":"Columbus"}
重构后的模型:
public class Person { public string Name {get;set;} public AddressM AddressM {get;set;} } public class AddressM { public string Address {get;set;} public string City {get;set;} }
需要将旧格式的JSON反序列化为新的Person类并保留地址字段,询问是否可通过Newtonsoft实现属性迁移,还是必须手动处理动态对象。
解决方案
不需要反序列化为动态对象,Newtonsoft提供多种方式处理这种属性迁移,以下是几种实用方案:
方案1:私有属性映射(最简洁)
在新Person类中添加私有属性,通过JsonProperty绑定旧JSON的字段,并在setter中自动填充AddressM:
public class Person { public string Name {get;set;} public AddressM AddressM {get;set;} = new AddressM(); [JsonProperty("Address")] private string OldAddress { set => AddressM.Address = value; } [JsonProperty("City")] private string OldCity { set => AddressM.City = value; } }
反序列化时,Newtonsoft会自动识别旧JSON中的Address和City字段,赋值给私有属性后同步到AddressM对象。
方案2:自定义JsonConverter(最灵活)
编写自定义转换器,直接控制旧JSON到新模型的映射逻辑:
public class PersonConverter : JsonConverter<Person> { public override Person ReadJson(JsonReader reader, Type objectType, Person existingValue, bool hasExistingValue, JsonSerializer serializer) { JObject obj = JObject.Load(reader); return new Person { Name = obj["Name"]?.ToString(), AddressM = new AddressM { Address = obj["Address"]?.ToString(), City = obj["City"]?.ToString() } }; } public override void WriteJson(JsonWriter writer, Person value, JsonSerializer serializer) { // 如需将新模型序列化为旧格式,可在此处理;无需则可省略或默认序列化 JObject obj = new JObject(); obj["Name"] = value.Name; obj["Address"] = value.AddressM?.Address; obj["City"] = value.AddressM?.City; obj.WriteTo(writer); } }
使用时指定转换器即可:
Person person = JsonConvert.DeserializeObject<Person>(oldJson, new PersonConverter());
也可以在Person类上标记[JsonConverter(typeof(PersonConverter))],让转换器自动生效。
方案3:反序列化回调
利用Newtonsoft的OnDeserialized特性,在反序列化完成后手动迁移字段:
public class Person { public string Name {get;set;} public AddressM AddressM {get;set;} = new AddressM(); [JsonProperty("Address")] private string TempAddress {get;set;} [JsonProperty("City")] private string TempCity {get;set;} [OnDeserialized] private void OnDeserialized(StreamingContext context) { AddressM.Address = TempAddress; AddressM.City = TempCity; // 清空临时属性避免序列化时输出 TempAddress = null; TempCity = null; } }
内容的提问来源于stack exchange,提问作者user815362
相关产品推荐
相关产品推荐

