Swashbuckle 5.6.3无法为Enum生成Schema的问题求助
问题:Swashbuckle 5.6.3中[FromQuery]参数枚举类型在启用UseAllOfToExtendReferenceSchemas时解析失败
代码结构
控制器代码
// 控制器方法 GetProducts(string id, [FromQuery] Product)
Product类与枚举定义
public class Product { public EnumA ExampleA { get; set; } } // 枚举类型 public enum EnumA { Option1, Option2 }
Startup.cs配置
services.AddSwaggerGen(c => { c.UseAllOfToExtendReferenceSchemas(); });
问题现象
通过Swagger UI查看获取产品的API时出现EnumA解析错误:生成的Swagger JSON文件中,paths部分引用了EnumA,但components/schemas里没有该枚举的定义,关键片段如下:
// JSON的paths片段 { "name": "ExampleA", "in": "query", "schema": { "allOf": [ { "$ref": "#/components/schemas/EnumA" } ] } }
已尝试的无效方法
- 移除
c.UseAllOfToExtendReferenceSchemas();可解决问题,但不符合需求; - 将参数注解从
[FromQuery]改为[FromBody]能生成枚举的Schema,但不符合需求; - 创建DocumentFilter手动添加EnumA到Schema定义,运行时抛出错误。
适配需求的解决建议
方案1:使用SchemaFilter手动注册枚举类型
编写SchemaFilter,在Schema生成过程中主动将EnumA添加到组件schemas集合中,避免DocumentFilter的运行时错误:
public class EnumSchemaFilter : ISchemaFilter { public void Apply(OpenApiSchema schema, SchemaFilterContext context) { var targetType = typeof(EnumA); if (context.Type == targetType && !context.SchemaRepository.Schemas.ContainsKey(targetType.Name)) { var enumSchema = new OpenApiSchema { Type = "string", Enum = Enum.GetNames(targetType) .Select(name => new OpenApiString(name)) .Cast<IOpenApiAny>() .ToList(), Description = "EnumA枚举类型说明" }; context.SchemaRepository.Schemas[targetType.Name] = enumSchema; } } }
在Startup.cs中注册该Filter:
services.AddSwaggerGen(c => { c.UseAllOfToExtendReferenceSchemas(); c.SchemaFilter<EnumSchemaFilter>(); });
方案2:使用OperationFilter修正Query参数的引用
如果方案1仍有问题,编写OperationFilter遍历所有Query参数,将引用的EnumA替换为直接的枚举定义,确保Swagger能正确识别:
public class QueryEnumFixerFilter : IOperationFilter { public void Apply(OpenApiOperation operation, OperationFilterContext context) { foreach (var parameter in operation.Parameters.ToList()) { if (parameter.In != ParameterLocation.Query || parameter.Schema?.AllOf == null) continue; var enumRef = parameter.Schema.AllOf.FirstOrDefault(s => s.Reference?.Id == nameof(EnumA)); if (enumRef != null) { var enumType = typeof(EnumA); parameter.Schema = new OpenApiSchema { Type = "string", Enum = Enum.GetNames(enumType) .Select(name => new OpenApiString(name)) .Cast<IOpenApiAny>() .ToList() }; } } } }
注册到SwaggerGen:
services.AddSwaggerGen(c => { c.UseAllOfToExtendReferenceSchemas(); c.OperationFilter<QueryEnumFixerFilter>(); });
内容的提问来源于stack exchange,提问作者John Doe
相关产品推荐
相关产品推荐

