You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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));

目前遇到两个问题:

  1. 仅支持大写开头的枚举值(如Documents),小写形式(如documents)无法被识别,需要实现大小写兼容;
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 07:26:05