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

ASP.NET Web API:保留JsonPropertyName同时用原属性名接收请求

在ASP.NET Web API中支持多命名格式的JSON请求体

方法一:添加多个JsonPropertyName特性(.NET 7+适用)

从.NET 7开始,System.Text.Json允许给同一个属性添加多个[JsonPropertyName]特性,直接实现同时识别多种命名的JSON字段,完全不影响原有特性的功能。

示例代码:

public class Questionnaire
{
    // 同时兼容patientEmail(原属性名)和patient_email(蛇形命名)
    [JsonPropertyName("patient_email")]
    [JsonPropertyName("patientEmail")]
    public string PatientEmail { get; set; }

    // 其他属性同理配置
    [JsonPropertyName("visit_date")]
    [JsonPropertyName("visitDate")]
    public DateTime VisitDate { get; set; }
}

配置后,接口既能接收{"patient_email":"xxx@xxx.com"}这类蛇形命名的请求,也能识别{"patientEmail":"xxx@xxx.com"}格式的payload,后续序列化调用其他API时,依然会使用JsonPropertyName指定的蛇形命名。

方法二:自定义JSON转换器(兼容.NET 6及更早版本)

如果项目基于.NET 6或更早版本,不支持多JsonPropertyName特性,可以自定义转换器实现多命名解析,同时保留原有序列化逻辑。

步骤1:编写自定义转换器

public class MultiNameJsonConverter<T> : JsonConverter<T> where T : class, new()
{
    public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        using JsonDocument doc = JsonDocument.ParseValue(ref reader);
        var targetObj = new T();
        var properties = typeToConvert.GetProperties(BindingFlags.Public | BindingFlags.Instance);

        foreach (var prop in properties)
        {
            // 获取特性指定的蛇形命名
            var jsonAttr = prop.GetCustomAttribute<JsonPropertyNameAttribute>();
            string snakeName = jsonAttr?.Name;
            // 原属性名(如果需要兼容小驼峰可自行转换,比如Char.ToLowerInvariant(prop.Name[0]) + prop.Name.Substring(1))
            string originalName = prop.Name;

            // 优先匹配蛇形命名,再匹配原属性名
            if (doc.RootElement.TryGetProperty(snakeName, out JsonElement snakeValue))
            {
                prop.SetValue(targetObj, JsonSerializer.Deserialize(snakeValue.GetRawText(), prop.PropertyType));
            }
            else if (doc.RootElement.TryGetProperty(originalName, out JsonElement originalValue))
            {
                prop.SetValue(targetObj, JsonSerializer.Deserialize(originalValue.GetRawText(), prop.PropertyType));
            }
        }
        return targetObj;
    }

    public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
    {
        // 序列化时仍保留原有特性的蛇形命名逻辑
        JsonSerializer.Serialize(writer, value, options);
    }
}

步骤2:注册转换器

在Program.cs(或Startup.cs)中配置JSON选项:

// .NET 6+ 配置示例
builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.Converters.Add(new MultiNameJsonConverter<Questionnaire>());
        // 保持原有序列化规则,不覆盖JsonPropertyName特性
        options.JsonSerializerOptions.PropertyNamingPolicy = null;
    });

注意事项

  • 方法一实现最简单,优先推荐.NET 7及以上版本使用;
  • 方法二如果涉及嵌套对象、复杂类型,需要扩展转换器的解析逻辑;
  • 两种方案都不会破坏原有JsonPropertyName特性的功能,序列化输出依然符合调用其他API的要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 22:22:39