Swagger枚举字符串化及成员隐藏后UI无法正常使用的解决方案求助
枚举Schema过滤器问题解决方案
问题描述
编写了如下Swagger Schema过滤器,用于隐藏标记了OpenApiIgnoreEnumAttribute的枚举成员,同时支持切换使用枚举值或枚举名称:
public class OpenApiIgnoreEnumSchemaFilter : ISchemaFilter { private readonly bool _useNames; public OpenApiIgnoreEnumSchemaFilter(bool useNames = false) { _useNames = useNames; } public void Apply(OpenApiSchema schema, SchemaFilterContext context) { if (!context.Type.IsEnum && !(Nullable.GetUnderlyingType(context.Type)?.IsEnum ?? false)) { return; } Type type = (context.Type.IsEnum ? context.Type : Nullable.GetUnderlyingType(context.Type)); List<IOpenApiAny> list = new List<IOpenApiAny>(); string[] names = Enum.GetNames(type); int[] values = Enum.GetValues(type).Cast<int>().ToArray(); foreach (var (text, value) in names.Select((string name, int index) => (name, values[index])).ToList()) { if (!type.GetMember(text)[0].GetCustomAttributes<OpenApiIgnoreEnumAttribute>().Any()) { IOpenApiAny item; if (!_useNames) { IOpenApiAny openApiAny = new OpenApiInteger(value); item = openApiAny; } else { IOpenApiAny openApiAny = new OpenApiString(text); item = openApiAny; } list.Add(item); } } schema.Enum = list; } }
但当构造函数传入true(即使用枚举名称)时,在SwaggerUI下拉菜单选择字符串化枚举值,系统提示仅允许整数值,需要保留原有功能的同时解决该问题。
问题原因
过滤器仅替换了schema.Enum的内容,但未同步修改Schema的Type和Format属性。默认情况下枚举对应的Schema类型是integer,即使枚举项换成字符串,Swagger仍会按整数类型校验输入,导致报错。
修改后的过滤器代码
public class OpenApiIgnoreEnumSchemaFilter : ISchemaFilter { private readonly bool _useNames; public OpenApiIgnoreEnumSchemaFilter(bool useNames = false) { _useNames = useNames; } public void Apply(OpenApiSchema schema, SchemaFilterContext context) { if (!context.Type.IsEnum && !(Nullable.GetUnderlyingType(context.Type)?.IsEnum ?? false)) { return; } Type enumType = context.Type.IsEnum ? context.Type : Nullable.GetUnderlyingType(context.Type); List<IOpenApiAny> enumItems = new List<IOpenApiAny>(); string[] enumNames = Enum.GetNames(enumType); int[] enumValues = Enum.GetValues(enumType).Cast<int>().ToArray(); foreach (var (name, value) in enumNames.Select((n, idx) => (n, enumValues[idx]))) { // 跳过标记了忽略属性的枚举成员 if (enumType.GetMember(name)[0].GetCustomAttributes<OpenApiIgnoreEnumAttribute>().Any()) { continue; } IOpenApiAny enumItem = _useNames ? (IOpenApiAny)new OpenApiString(name) : new OpenApiInteger(value); enumItems.Add(enumItem); } schema.Enum = enumItems; // 根据useNames设置对应的Schema类型 if (_useNames) { schema.Type = "string"; schema.Format = null; // 清除默认的integer格式 // 如果有默认值,同步转换为字符串类型 if (schema.Default is OpenApiInteger defaultInt) { var defaultName = Enum.GetName(enumType, defaultInt.Value); schema.Default = new OpenApiString(defaultName); } } else { // 保持默认的整数类型设置 schema.Type = "integer"; schema.Format = "int32"; } } }
关键修改说明
- 当
_useNames=true时,将schema.Type设为"string"并清空Format,让Swagger识别该字段为字符串类型 - 同步处理Schema的默认值:如果原来的默认值是整数类型,转换为对应的枚举名称字符串,保持数据一致性
- 优化代码结构,简化枚举项的创建逻辑
内容的提问来源于stack exchange,提问作者Marek M.
相关产品推荐
相关产品推荐

