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
相关产品推荐
相关产品推荐

