使用Swashbuckle AspNetCore时生成的UI文档不识别JsonProperty值
解决Swagger显示Newtonsoft.Json.JsonProperty标注的Query参数名问题
这个问题的核心在于Swashbuckle(生成Swagger文档的库)默认不会自动识别Newtonsoft.Json的JsonProperty属性——它默认依赖System.Text.Json的注解或者直接使用C#属性名,所以即便你用JsonProperty标注了$top这类规范参数名,Swagger还是会显示原属性名。
下面提供两种可靠的解决方案,推荐第一种官方支持的方式:
方案一:启用Swashbuckle对Newtonsoft.Json的原生支持
这是最简洁的解决方式,只需要两步:
安装对应的NuGet包
打开NuGet包管理器,安装Swashbuckle.AspNetCore.Newtonsoft包(版本要和你当前的Swashbuckle.AspNetCore版本匹配)。配置Program.cs中的Swagger和Controllers
修改你的服务配置代码,让Swagger和MVC控制器都使用Newtonsoft.Json处理序列化和注解:
var builder = WebApplication.CreateBuilder(args); // 添加控制器,并配置使用Newtonsoft.Json builder.Services.AddControllers() .AddNewtonsoftJson(options => { // 这里可以根据需求添加Newtonsoft的序列化配置,比如契约解析器 options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); }); // 配置Swagger,并启用Newtonsoft.Json支持 builder.Services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "Your API", Version = "v1" }); // 关键:启用Newtonsoft.Json的注解识别 c.UseNewtonsoftJson(); }); var app = builder.Build(); // 中间件配置... app.UseSwagger(); app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "Your API V1"); }); app.UseAuthorization(); app.MapControllers(); app.Run();
配置完成后,重新生成Swagger文档,你会看到Query参数已经显示为$orderBy、$top等你标注的名称了。
方案二:自定义Schema过滤器手动映射属性名
如果因为某些原因无法使用官方的Newtonsoft支持包,可以通过自定义Swagger的Schema过滤器来实现:
- 创建一个Schema过滤器类:
using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; using Newtonsoft.Json; using System.Reflection; public class NewtonsoftJsonPropertySchemaFilter : ISchemaFilter { public void Apply(OpenApiSchema schema, SchemaFilterContext context) { if (schema.Properties == null || context.Type == null) return; // 遍历类的所有属性,查找JsonProperty注解 foreach (var propertyInfo in context.Type.GetProperties()) { var jsonPropertyAttr = propertyInfo.GetCustomAttribute<JsonPropertyAttribute>(); if (jsonPropertyAttr == null) continue; // 如果Swagger当前的属性名是原C#属性名,替换为JsonProperty指定的名称 if (schema.Properties.TryGetValue(propertyInfo.Name, out var openApiProperty)) { schema.Properties.Remove(propertyInfo.Name); schema.Properties.Add(jsonPropertyAttr.PropertyName, openApiProperty); } } } }
- 在Swagger配置中注册这个过滤器:
builder.Services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "Your API", Version = "v1" }); // 添加自定义过滤器 c.SchemaFilter<NewtonsoftJsonPropertySchemaFilter>(); });
这种方式会手动扫描每个类的JsonProperty注解,替换Swagger Schema中的属性名,同样能达到你想要的效果。
为什么之前的MapType方法没用?
MapType是用来手动映射整个类型的Schema,而你的问题是单个属性的名称不匹配,它无法处理属性级别的注解映射,所以这就是为什么之前尝试MapType没有解决问题的原因。
内容的提问来源于stack exchange,提问作者Scott
相关产品推荐
相关产品推荐

