You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 21:33:12