如何在ASP.NET Core Minimal API路由中正确解析枚举?
ASP.NET Core Minimal API路由枚举的Swagger配置问题
问题场景
在ASP.NET Core控制器中使用枚举作为路由参数时,添加JsonStringEnumConverter配置后,Swagger/OpenAPI能正确识别枚举类型,生成的参数定义会引用枚举组件:
"parameters": [ { "name": "location", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/Location" } } ]
但在Minimal API中使用相同枚举和配置后,Swagger仍将路由参数识别为字符串类型,参数定义如下:
"parameters": [ { "name": "location", "in": "path", "required": true, "style": "simple", "schema": { "type": "string" } } ]
控制器配置示例:
builder.Services.AddControllers() .AddJsonOptions(options => options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()));
Minimal API代码示例:
public enum Location { London } app.MapGet("/weatherforecast/{location}", (Location location) => { // 业务逻辑 }) .WithName("GetWeatherForecast") .WithOpenApi();
解决方案
要让Minimal API的路由枚举参数被Swagger正确识别,需在原有配置基础上添加Swagger参数过滤逻辑,具体步骤如下:
1. 保留枚举序列化配置
确保已添加JsonStringEnumConverter配置,保证枚举与字符串的序列化/反序列化正常:
builder.Services.ConfigureHttpJsonOptions(options => { options.SerializerOptions.Converters.Add(new JsonStringEnumConverter()); }); builder.Services.Configure<Microsoft.AspNetCore.Mvc.JsonOptions>(options => { options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); });
2. 添加Swagger枚举参数过滤器
配置Swagger生成器,添加自定义参数过滤器,将枚举类型的路由参数关联到对应的枚举组件:
builder.Services.AddSwaggerGen(options => { options.ParameterFilter<EnumRouteParameterFilter>(); }); // 自定义枚举参数过滤器 public class EnumRouteParameterFilter : IParameterFilter { public void Apply(OpenApiParameter parameter, ParameterFilterContext context) { var parameterType = context.ParameterInfo?.ParameterType ?? context.ParameterDescriptor?.ParameterType; if (parameterType != null && parameterType.IsEnum) { var enumSchema = context.SchemaGenerator.GenerateSchema(parameterType, context.SchemaRepository); parameter.Schema = enumSchema; parameter.Schema.Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = parameterType.FullName ?? parameterType.Name }; } } }
3. 可选:支持大小写不敏感的路由枚举绑定
如果需要让路由枚举参数支持大小写不敏感(比如london也能匹配Location.London),可添加路由约束配置:
builder.Services.Configure<RouteOptions>(options => { options.ConstraintMap.Add("enum", typeof(StringEnumRouteConstraint)); }); // 自定义字符串枚举路由约束 public class StringEnumRouteConstraint : IRouteConstraint { public bool Match(HttpContext? httpContext, IRouter? route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection) { if (!values.TryGetValue(routeKey, out var value) || value is not string stringValue) return false; var parameterType = context.ParameterDescriptor?.ParameterType; if (parameterType == null || !parameterType.IsEnum) return false; return Enum.TryParse(parameterType, stringValue, ignoreCase: true, out _); } }
之后在Minimal API端点中可显式指定路由约束(可选):
app.MapGet("/weatherforecast/{location:enum}", (Location location) => { // 业务逻辑 }) .WithName("GetWeatherForecast") .WithOpenApi();
配置完成后,Swagger将正确识别路由中的枚举参数,生成的OpenAPI文档会和控制器场景一致,参数schema引用对应的枚举组件。
内容的提问来源于stack exchange,提问作者Peter
相关产品推荐
相关产品推荐

