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

可否扩展Newtonsoft.Json的JsonProperty特性新增自定义序列化属性?

原生JsonPropertyAttribute是密封类,无法直接继承扩展新增自定义属性,但可以通过「自定义多场景名称特性+对应场景合约解析器」的方案实现你要的多场景序列化字段名需求,完全可以达到你期望的使用效果。


步骤1:自定义多场景序列化名称特性

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class JsonMultiSceneNameAttribute : Attribute
{
    // Solver场景对应序列化字段名
    public string SolverPropertyName { get; set; }
    // API场景对应序列化字段名
    public string APIPropertyName { get; set; }
    // 后续新增场景只需在此处加对应属性即可
}

步骤2:实现不同场景的定制合约解析器

Solver场景解析器

序列化时优先使用标记的SolverPropertyName作为字段名:

public class SolverSceneContractResolver : DefaultContractResolver
{
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        var properties = base.CreateProperties(type, memberSerialization);
        foreach (var prop in properties)
        {
            // 获取属性上标记的自定义多场景特性
            var multiNameAttr = prop.AttributeProvider
                .GetAttributes(typeof(JsonMultiSceneNameAttribute), false)
                .Cast<JsonMultiSceneNameAttribute>()
                .FirstOrDefault();
            
            if (multiNameAttr != null && !string.IsNullOrWhiteSpace(multiNameAttr.SolverPropertyName))
            {
                prop.PropertyName = multiNameAttr.SolverPropertyName;
            }
        }
        return properties;
    }
}

API场景解析器

序列化时优先使用标记的APIPropertyName作为字段名:

public class APISceneContractResolver : DefaultContractResolver
{
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        var properties = base.CreateProperties(type, memberSerialization);
        foreach (var prop in properties)
        {
            var multiNameAttr = prop.AttributeProvider
                .GetAttributes(typeof(JsonMultiSceneNameAttribute), false)
                .Cast<JsonMultiSceneNameAttribute>()
                .FirstOrDefault();
            
            if (multiNameAttr != null && !string.IsNullOrWhiteSpace(multiNameAttr.APIPropertyName))
            {
                prop.PropertyName = multiNameAttr.APIPropertyName;
            }
        }
        return properties;
    }
}

SmartModel存储场景解析器

直接使用原生属性名作为序列化字段名:

public class SmartModelStorageContractResolver : DefaultContractResolver
{
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        var properties = base.CreateProperties(type, memberSerialization);
        foreach (var prop in properties)
        {
            prop.PropertyName = prop.UnderlyingName;
        }
        return properties;
    }
}

步骤3:给模型类标记特性

和你期望的写法几乎一致,只是特性名换成自定义的即可:

class Pipe
{
    [JsonMultiSceneName(
        SolverPropertyName = "z_axis_dimension", 
        APIPropertyName = "distance")]
    public double Length { get; set; }

    [JsonMultiSceneName(
        SolverPropertyName = "cross_sectional_dimension", 
        APIPropertyName = "diameter")]
    public double Diameter { get; set; }
}

步骤4:不同场景序列化调用示例

var pipe = new Pipe
{
    Length = 10.2,
    Diameter = 5.5
};

// 序列化得到SolverDTO
var solverSettings = new JsonSerializerSettings
{
    Formatting = Formatting.Indented,
    ContractResolver = new SolverSceneContractResolver()
};
string solverJson = JsonConvert.SerializeObject(pipe, solverSettings);

// 序列化得到API用DTO
var apiSettings = new JsonSerializerSettings
{
    Formatting = Formatting.Indented,
    ContractResolver = new APISceneContractResolver()
};
string apiJson = JsonConvert.SerializeObject(pipe, apiSettings);

// 序列化得到存储用SmartModelDTO
var storageSettings = new JsonSerializerSettings
{
    Formatting = Formatting.Indented,
    ContractResolver = new SmartModelStorageContractResolver()
};
string storageJson = JsonConvert.SerializeObject(pipe, storageSettings);

补充说明

该方案比修改/扩展原生JsonProperty的灵活性更高,后续新增其他序列化场景时,仅需做两处修改:

  1. 在JsonMultiSceneNameAttribute中新增对应场景的名称属性
  2. 新增对应场景的合约解析器即可,无需调整已有模型的标记逻辑

内容的提问来源于stack exchange,提问作者Francois Louw

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 09:36:06