.NET 8 Minimal API枚举参数大小写兼容及Swagger显示问题求助
.NET 8 Minimal API 枚举参数大小写兼容与Swagger显示优化
问题场景
我维护一个.NET 8 Minimal API,接口通过路由接收枚举类型参数,核心代码如下:
路由定义:
app.MapGet("/{id}/attachments/{category}/{attachmentId}", async ( Guid id, AttachmentCategory category, string attachmentId) => { // 业务逻辑实现 })
枚举类型:
public enum AttachmentCategory { Documents, Photos }
JSON序列化配置:
options.SerializerOptions.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase));
目前遇到两个问题:
- 仅支持大写开头的枚举值(如
Documents),小写形式(如documents)无法被识别,需要实现大小写兼容; - Swagger文档中该枚举参数显示为普通字符串类型,而非枚举下拉选项,想知道是否必须通过
IDocumentFilter解决。
解决方案
一、实现枚举参数大小写兼容
默认的JsonStringEnumConverter不支持大小写不敏感的反序列化,我们可以自定义一个转换器来解决:
1. 自定义大小写不敏感枚举转换器
public class CaseInsensitiveJsonStringEnumConverter : JsonStringEnumConverter { public CaseInsensitiveJsonStringEnumConverter(JsonNamingPolicy namingPolicy = null) : base(namingPolicy, allowIntegerValues: true) { } public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.String) { var enumStr = reader.GetString(); if (!string.IsNullOrWhiteSpace(enumStr) && Enum.TryParse(typeToConvert, enumStr, ignoreCase: true, out var result)) { return result; } } // 解析失败时 fallback 到默认逻辑 return base.Read(ref reader, typeToConvert, options); } }
2. 替换原有转换器
将Program.cs中原有的JsonStringEnumConverter替换为自定义的转换器:
options.SerializerOptions.Converters.Add(new CaseInsensitiveJsonStringEnumConverter(JsonNamingPolicy.CamelCase));
这样无论传入Documents、documents还是DOCUMENTS,都能被正确解析为对应的枚举值。
补充:路由参数绑定强化(可选)
如果需要确保路由参数的绑定也严格支持大小写不敏感,可以配置路由选项并添加枚举约束:
builder.Services.Configure<RouteOptions>(options => { options.ConstraintMap["enum"] = typeof(EnumRouteConstraint); });
然后修改路由定义,添加enum约束:
app.MapGet("/{id}/attachments/{category:enum}/{attachmentId}", async ( Guid id, AttachmentCategory category, string attachmentId) => { // 业务逻辑 })
不过自定义转换器已经能覆盖绝大多数场景,这个步骤可按需添加。
二、修复Swagger枚举参数显示问题
不需要仅依赖IDocumentFilter,有更简洁的配置方式:
1. 基础配置:启用Swagger枚举支持
在Program.cs的SwaggerGen配置中,添加以下设置:
builder.Services.AddSwaggerGen(options => { // 禁止将所有枚举描述为字符串,让Swagger显示枚举选项 options.DescribeAllEnumsAsStrings(false); // 可选:将枚举定义内联到参数说明中 options.UseInlineDefinitionsForEnums(); });
这个配置会让Swagger自动识别枚举类型,并将参数渲染为下拉选择框,而非纯字符串输入。
2. 备选方案:自定义SchemaFilter(如果基础配置无效)
如果上述配置不生效,可以添加一个简单的ISchemaFilter来强制处理枚举:
public class EnumSchemaFilter : ISchemaFilter { public void Apply(OpenApiSchema schema, SchemaFilterContext context) { if (!context.Type.IsEnum) return; schema.Enum.Clear(); foreach (var enumValue in Enum.GetValues(context.Type)) { schema.Enum.Add(new OpenApiString(Enum.GetName(context.Type, enumValue))); } schema.Type = "string"; schema.Format = null; } }
然后在SwaggerGen配置中注册这个过滤器:
builder.Services.AddSwaggerGen(options => { options.SchemaFilter<EnumSchemaFilter>(); });
内容的提问来源于stack exchange,提问作者Jester
相关产品推荐
相关产品推荐

