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

ASP.NET Core中基于控制器条件序列化重命名属性的实现

基于System.Text.Json实现ASP.NET Core控制器特定属性重命名

解决方案思路

通过自定义JsonConverterFactory实现针对特定模型类的属性名称映射,再将该转换器注入到自定义的ExternalJsonOutputFormatter中,最后配置目标控制器使用此格式化器,默认控制器保留原有序列化规则。

步骤1:定义模型类

public class ClassA
{
    public string OriginalPropA1 { get; set; }
    public int OriginalPropA2 { get; set; }
    public string NormalProp { get; set; }
}

public class ClassB
{
    public string OriginalPropB1 { get; set; }
    public bool NormalPropB { get; set; }
}

步骤2:实现自定义属性重命名转换器

创建JsonConverterFactory子类,针对ClassA和ClassB配置属性名映射,在序列化时替换属性名称:

public class CustomPropertyRenameConverter : JsonConverterFactory
{
    // 配置模型类的属性名映射关系
    private readonly Dictionary<Type, Dictionary<string, string>> _propertyMappings = new()
    {
        {
            typeof(ClassA),
            new Dictionary<string, string>
            {
                { nameof(ClassA.OriginalPropA1), "RenamedA1" },
                { nameof(ClassA.OriginalPropA2), "RenamedA2" }
            }
        },
        {
            typeof(ClassB),
            new Dictionary<string, string>
            {
                { nameof(ClassB.OriginalPropB1), "RenamedB1" }
            }
        }
    };

    public override bool CanConvert(Type typeToConvert)
    {
        return _propertyMappings.ContainsKey(typeToConvert);
    }

    public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
    {
        var converterType = typeof(CustomRenameConverter<>).MakeGenericType(typeToConvert);
        return (JsonConverter)Activator.CreateInstance(converterType, _propertyMappings[typeToConvert]);
    }

    // 泛型转换器实现具体序列化逻辑
    private class CustomRenameConverter<T> : JsonConverter<T>
    {
        private readonly Dictionary<string, string> _propertyMap;
        private readonly JsonConverter<T> _defaultConverter;

        public CustomRenameConverter(Dictionary<string, string> propertyMap)
        {
            _propertyMap = propertyMap;
            _defaultConverter = (JsonConverter<T>)JsonSerializerOptions.Default.GetConverter(typeof(T));
        }

        // 无需自定义反序列化,直接使用默认实现
        public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            return _defaultConverter.Read(ref reader, typeToConvert, options);
        }

        public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
        {
            // 先序列化为JsonDocument,再遍历替换属性名
            using var jsonDoc = JsonDocument.Parse(JsonSerializer.Serialize(value, options));
            writer.WriteStartObject();

            foreach (var property in jsonDoc.RootElement.EnumerateObject())
            {
                var propertyName = _propertyMap.TryGetValue(property.Name, out var newName) ? newName : property.Name;
                writer.WritePropertyName(propertyName);
                property.Value.WriteTo(writer);
            }

            writer.WriteEndObject();
        }
    }
}

步骤3:修改自定义输出格式化器

在ExternalJsonOutputFormatter中注入自定义转换器,确保序列化时应用属性重命名规则:

public class ExternalJsonOutputFormatter : SystemTextJsonOutputFormatter
{
    public ExternalJsonOutputFormatter(JsonSerializerOptions options) : base(CreateCustomOptions(options))
    {
    }

    private static JsonSerializerOptions CreateCustomOptions(JsonSerializerOptions baseOptions)
    {
        var customOptions = new JsonSerializerOptions(baseOptions);
        // 添加属性重命名转换器
        customOptions.Converters.Add(new CustomPropertyRenameConverter());
        return customOptions;
    }
}

步骤4:注册格式化器并配置控制器

在Program.cs中注册自定义格式化器,并确保XController使用该格式化器:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers(options =>
{
    // 获取默认Json配置作为基础
    var baseJsonOptions = new JsonSerializerOptions(SystemTextJsonSerializerProvider.DefaultSerializerOptions);
    // 将自定义格式化器插入到输出格式化器列表首位
    options.OutputFormatters.Insert(0, new ExternalJsonOutputFormatter(baseJsonOptions));
})
// 配置默认Json序列化规则(供YController使用)
.AddJsonOptions(options =>
{
    options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
});

var app = builder.Build();

app.UseRouting();
app.MapControllers();
app.Run();

步骤5:编写控制器代码

XController返回模型时会自动应用属性重命名,YController使用默认规则:

[ApiController]
[Route("api/x")]
public class XController : ControllerBase
{
    [HttpGet("classa")]
    public IActionResult GetClassA()
    {
        return Ok(new ClassA
        {
            OriginalPropA1 = "TestA1",
            OriginalPropA2 = 123,
            NormalProp = "Normal"
        });
        // 输出:{"RenamedA1":"TestA1","RenamedA2":123,"NormalProp":"Normal"}
    }

    [HttpGet("classb")]
    public IActionResult GetClassB()
    {
        return Ok(new ClassB
        {
            OriginalPropB1 = "TestB1",
            NormalPropB = true
        });
        // 输出:{"RenamedB1":"TestB1","NormalPropB":true}
    }
}

[ApiController]
[Route("api/y")]
public class YController : ControllerBase
{
    [HttpGet("classa")]
    public IActionResult GetClassA()
    {
        return Ok(new ClassA
        {
            OriginalPropA1 = "TestA1",
            OriginalPropA2 = 123,
            NormalProp = "Normal"
        });
        // 输出(默认驼峰):{"originalPropA1":"TestA1","originalPropA2":123,"normalProp":"Normal"}
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 07:47:44