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

如何自定义DefaultContractResolver实现JSON与多模型的属性映射?

自定义DefaultContractResolver解决跨模型JSON属性映射问题

当需要在不修改现有模型(不能重命名、添加特性)的前提下,实现JSON字段到不同模型属性的差异化映射时,常规的ResolvePropertyName方法无法区分属性所属的类型,此时可以通过重写DefaultContractResolver的CreateProperty方法来实现细粒度的映射控制。

实现思路

重写CreateProperty方法,通过MemberInfo.DeclaringType判断当前属性所属的模型类,再根据属性名称指定对应的JSON字段名,以此解决同一JSON字段对应不同模型属性的问题(比如JSON中的id对应Alarm.AlarmId和Setting.SettId)。

代码实现

自定义ContractResolver

using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System.Reflection;

public class CustomContractResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty property = base.CreateProperty(member, memberSerialization);

        // 处理Alarm类的属性映射
        if (member.DeclaringType == typeof(Alarm))
        {
            switch (member.Name)
            {
                case nameof(Alarm.AlarmId):
                    property.PropertyName = "id";
                    break;
                case nameof(Alarm.AlarmName):
                    property.PropertyName = "name";
                    break;
                case nameof(Alarm.RbcType):
                    property.PropertyName = "type";
                    break;
                case nameof(Alarm.MinimumTolerated):
                    property.PropertyName = "min";
                    break;
                case nameof(Alarm.MaximumTolerated):
                    property.PropertyName = "max";
                    break;
            }
        }
        // 处理Setting类的属性映射
        else if (member.DeclaringType == typeof(Setting))
        {
            switch (member.Name)
            {
                case nameof(Setting.SettId):
                    property.PropertyName = "id";
                    break;
                case nameof(Setting.IntValue):
                    property.PropertyName = "value";
                    break;
            }
        }

        return property;
    }
}

使用示例

// 反序列化
string json = @"{""parameter"": {""alarms"": [{""id"":1,""name"":""alarm1"",""type"":5,""min"":0,""max"":2}],""settings"": [{""id"":1,""name"":""setting1"",""description"":""something here"",""type"":1,""value"":2}]}}";

var serializerSettings = new JsonSerializerSettings
{
    ContractResolver = new CustomContractResolver()
};

var parameterModel = JsonConvert.DeserializeObject<Parameter>(json, serializerSettings);

// 序列化
var parameterToSerialize = new Parameter
{
    Alarms = new List<Alarm>
    {
        new Alarm 
        { 
            AlarmId = 1, 
            AlarmName = "alarm1", 
            RbcType = AlarmType.Type5, 
            MinimumTolerated = 0, 
            MaximumTolerated = 2 
        }
    },
    Settings = new List<Setting>
    {
        new Setting 
        { 
            SettId = 1, 
            Name = "setting1", 
            Description = "something here", 
            Type = SettingType.Type1, 
            IntValue = 2 
        }
    }
};

string serializedJson = JsonConvert.SerializeObject(parameterToSerialize, serializerSettings);

扩展说明

如果后续新增其他需要映射的模型,只需在CreateProperty方法中添加对应的类型判断分支和属性映射规则即可,全程无需修改原有模型代码,完全符合需求约束。

内容的提问来源于stack exchange,提问作者Jaime Oliveira

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 15:10:23