ASP.NET Core 3.1能否同时支持JSON驼峰式与蛇形命名策略?
ASP.NET Core 同时支持JSON驼峰与蛇形命名的配置方案
针对项目需要同时兼容驼峰(camelCase)和蛇形(snake_case)命名参数的场景,可根据项目使用的JSON序列化库选择以下配置方案:
方案一:使用默认System.Text.Json实现兼容
如果项目使用ASP.NET Core默认的System.Text.Json,可通过添加多输入格式化器的方式,让系统自动适配两种命名格式:
- 在
Program.cs中配置控制器服务,添加蛇形命名的输入格式化器:
builder.Services.AddControllers(options => { // 获取默认的驼峰命名JSON输入格式化器 var camelCaseFormatter = options.InputFormatters.OfType<SystemTextJsonInputFormatter>().FirstOrDefault(); if (camelCaseFormatter != null) { // 复制原有配置并修改为蛇形命名策略 var snakeCaseOptions = new JsonSerializerOptions(camelCaseFormatter.SerializerOptions) { PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower }; var snakeCaseFormatter = new SystemTextJsonInputFormatter(snakeCaseOptions); // 将蛇形格式化器添加到列表,放在驼峰格式化器之后 options.InputFormatters.Insert( options.InputFormatters.IndexOf(camelCaseFormatter) + 1, snakeCaseFormatter ); } }) .AddJsonOptions(options => { // 输出结果保持原有驼峰命名配置 options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; });
该配置会让接口优先尝试用驼峰格式解析请求参数,失败则自动切换为蛇形格式解析,输出仍保持驼峰命名,不影响原有业务。
方案二:使用Newtonsoft.Json(Json.NET)实现兼容
如果项目依赖Newtonsoft.Json,可通过自定义ContractResolver实现双命名兼容:
- 先安装NuGet包:
Microsoft.AspNetCore.Mvc.NewtonsoftJson - 自定义契约解析器,同时支持驼峰和蛇形命名映射:
public class CamelAndSnakeCaseContractResolver : DefaultContractResolver { protected override string ResolvePropertyName(string propertyName) { // 输出时保持驼峰命名 return CamelCasePropertyNamesContractResolver.Instance.ResolvePropertyName(propertyName); } protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { var property = base.CreateProperty(member, memberSerialization); // 生成当前属性对应的蛇形命名 var snakeCaseName = ConvertToSnakeCase(member.Name); // 允许接口接收蛇形命名的参数 property.ExtensionDataSetter = (instance, key, value) => { if (key.Equals(snakeCaseName, StringComparison.OrdinalIgnoreCase)) { (member as PropertyInfo)?.SetValue(instance, value); } }; return property; } private string ConvertToSnakeCase(string input) { if (string.IsNullOrEmpty(input)) return input; var sb = new StringBuilder(); sb.Append(char.ToLowerInvariant(input[0])); foreach (var c in input.Skip(1)) { if (char.IsUpper(c)) { sb.Append('_'); sb.Append(char.ToLowerInvariant(c)); } else { sb.Append(c); } } return sb.ToString(); } }
- 在
Program.cs中配置使用自定义解析器:
builder.Services.AddControllers() .AddNewtonsoftJson(options => { options.SerializerSettings.ContractResolver = new CamelAndSnakeCaseContractResolver(); // 开启属性名大小写不敏感,增强兼容性 options.SerializerSettings.Culture = CultureInfo.InvariantCulture; options.SerializerSettings.MetadataPropertyHandling = MetadataPropertyHandling.Ignore; });
注意事项
- 如果仅需兼容输入参数的两种命名,方案一的多格式化器方式更轻量,无需修改实体类;
- 若需要输出也同时支持两种命名,可调整配置中的输出策略(但通常建议输出保持统一格式);
- 测试时需分别用驼峰和蛇形命名的参数请求接口,验证参数是否能正确绑定。
内容的提问来源于stack exchange,提问作者Hoang Minh
相关产品推荐
相关产品推荐

