You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Newtonsoft JSON能否实现反序列化模型正确且序列化时修改属性名?

实现反序列化保留原名称,序列化修改属性名称的方案

当然可以做到!Newtonsoft.Json(Json.NET)提供了几种灵活的方式来实现这个需求——让模型在反序列化时匹配原始的JSON字段名,同时在序列化时输出自定义的属性名称。下面针对你的AccountingInspectionsResponseModel模型,给出两种实用方案:

方案一:使用自定义ContractResolver(推荐,无需修改模型结构)

这种方法不需要改动现有模型的JsonProperty特性,而是通过自定义契约解析器,在序列化阶段动态替换属性名称,反序列化时依然遵循原有的JsonProperty配置。

步骤1:定义自定义ContractResolver

public class CustomSerializationContractResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty property = base.CreateProperty(member, memberSerialization);
        
        // 根据属性名称映射序列化时的新名称,你可以按需修改这里的命名
        switch (member.Name)
        {
            case nameof(AccountingInspectionsResponseModel.OrganizationInfo):
                property.PropertyName = "custom_organization_info"; 
                break;
            case nameof(AccountingInspectionsResponseModel.Inspections):
                property.PropertyName = "custom_inspection_list"; 
                break;
            // 其他需要改名的属性都可以在这里添加映射
        }
        
        return property;
    }
}

步骤2:序列化时使用自定义Resolver

当你需要序列化模型时,将自定义解析器传入JsonSerializerSettings即可:

var model = new AccountingInspectionsResponseModel
{
    OrganizationInfo = new OrganizationInfo(),
    Inspections = new List<InspectionInfo>()
};

// 序列化配置
var settings = new JsonSerializerSettings
{
    ContractResolver = new CustomSerializationContractResolver(),
    Formatting = Formatting.Indented // 可选,让输出的JSON更易读
};

string serializedJson = JsonConvert.SerializeObject(model, settings);

而反序列化时直接用默认方式即可,完全不受影响:

string originalJson = "{\"subject_data\": {}, \"inspections\": []}";
var model = JsonConvert.DeserializeObject<AccountingInspectionsResponseModel>(originalJson);

方案二:拆分属性+JsonIgnore(适合简单场景)

如果你的模型结构不复杂,可以为每个需要改名的属性定义两个成员:一个用于反序列化(保留原JsonProperty),一个用于序列化(标记反序列化时忽略,指定新的JsonProperty),然后通过属性的get/set逻辑同步值。

修改后的模型示例:

public class AccountingInspectionsResponseModel
{
    // 仅用于反序列化,序列化时忽略
    [JsonProperty("subject_data")]
    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
    public OrganizationInfo OrganizationInfoDeserialized { get; set; }
    
    // 仅用于序列化,反序列化时忽略
    [JsonProperty("custom_organization_info")]
    [JsonIgnore(Condition = JsonIgnoreCondition.WhenReading)]
    public OrganizationInfo OrganizationInfo 
    { 
        get => OrganizationInfoDeserialized; 
        set => OrganizationInfoDeserialized = value; 
    }

    // Inspections属性同理处理
    [JsonProperty("inspections")]
    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
    public List<InspectionInfo> InspectionsDeserialized { get; set; }
    
    [JsonProperty("custom_inspection_list")]
    [JsonIgnore(Condition = JsonIgnoreCondition.WhenReading)]
    public List<InspectionInfo> Inspections
    {
        get => InspectionsDeserialized;
        set => InspectionsDeserialized = value;
    }
}

这种方式不需要额外的解析器,直接使用默认的序列化/反序列化方法即可,但会增加模型的代码量,适合属性较少的场景。

总结

  • 如果模型属性较多,推荐使用自定义ContractResolver,保持模型简洁,逻辑集中;
  • 如果是少量属性需要改名,拆分属性+JsonIgnore的方式更直接。

两种方案都能完美实现你的需求:反序列化时正确匹配原始JSON字段,序列化时输出你想要的属性名称。

内容的提问来源于stack exchange,提问作者Jaroslav Rumjakin

火山引擎 最新活动