Swagger因参数继承基类生成API文档时抛出500错误
问题场景
当ASP.NET Core接口的Action参数继承自抽象基类时,启动应用访问Swagger页面会触发500内部服务器错误,异常类型为Swashbuckle.AspNetCore.SwaggerGen.SwaggerGeneratorException,提示无法为目标Action生成Operation。
相关代码
接口Action
[HttpPost] [Route("documents/generate")] [ProducesResponseType(typeof(DocGenWorkflowAsyncResponse), StatusCodes.Status200OK)] [ProducesResponseType(typeof(DocGenWorkflowAsyncResponse), StatusCodes.Status500InternalServerError)] [ProducesResponseType(typeof(HttpResponse), StatusCodes.Status401Unauthorized)] [ProducesResponseType(typeof(HttpResponse), StatusCodes.Status400BadRequest)] [Trace("Generate Document Action")] public Task<IActionResult> Generate(MergeRequest mergeRequest) { return _triggerDocumentWorkflowAdapter.TriggerWorkflow(mergeRequest); }
参数类定义
public class MergeRequest : BaseRequest { } public abstract class BaseRequest {}
Swagger配置
services.AddSwaggerGen(swaggerGenOptions => { swaggerGenOptions.SwaggerDoc( ServiceInfo.Version, new OpenApiInfo { Title = ServiceInfo.Name, Version = ServiceInfo.Version }); var xmlFile = $"{Assembly.GetEntryAssembly()!.GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); swaggerGenOptions.IncludeXmlComments(xmlPath, includeControllerXmlComments: true); });
异常信息
{"SeverityText":"Error","Message":"Connection id "0HMRUS3P495NL", Request id "0HMRUS3P495NL:00000005": An unhandled exception was thrown by the application.","ClassName":"Microsoft.AspNetCore.Server.Kestrel","Attributes":{"ExceptionType":"Swashbuckle.AspNetCore.SwaggerGen.SwaggerGeneratorException","ExceptionMessage":"Failed to generate Operation for action - DocumentDove.Web.Controllers.DocumentsController.Generate (DocumentDove.Web). See inner exception","ExceptionStackTrace":" at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GenerateOperation(ApiDescription apiDescription, SchemaRepository schemaRepository)\r\n at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GenerateOperations(IEnumerable
1 apiDescriptions, SchemaRepository schemaRepository)\r\n at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GeneratePaths(IEnumerable1 apiDescriptions, SchemaRepository schemaRepository)\r\n at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GetSwaggerDocumentWithoutFilters(String documentName, String host, String basePath)\r\n at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GetSwaggerAsync(String documentName, String host, String basePath)\r\n at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)\r\n at Conga.Platform.Telemetry.Middlewares.TracingContextMiddleware.InvokeAsync(HttpContext context)\r\n at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)\r\n at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)\r\n at Microsoft.AspNetCore.Watch.BrowserRefresh.BrowserRefreshMiddleware.InvokeAsync(HttpContext context)\r\n at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)"},"TraceId":"ad9347b6f8e328b9d9a734cdda74d19d","SpanId":"b95f01ffbbcc115d","TraceFlags":0}
原因分析
Swashbuckle.AspNetCore在生成Swagger Schema时,默认无法正确处理抽象基类作为参数父类的情况,尤其是当基类没有任何可序列化属性时,生成器无法确定如何为继承结构生成有效的OpenAPI Schema,进而抛出异常。
解决方案
方案1:启用继承支持并配置Schema处理
修改Swagger配置,开启继承支持,并指定抽象基类的子类范围:
services.AddSwaggerGen(swaggerGenOptions => { swaggerGenOptions.SwaggerDoc( ServiceInfo.Version, new OpenApiInfo { Title = ServiceInfo.Name, Version = ServiceInfo.Version }); // 启用继承关系的Schema生成规则 swaggerGenOptions.UseAllOfForInheritance(); // 指定抽象基类对应的所有子类 swaggerGenOptions.SelectSubTypesUsing(baseType => { if (baseType == typeof(BaseRequest)) { return new[] { typeof(MergeRequest) }; } return Enumerable.Empty<Type>(); }); var xmlFile = $"{Assembly.GetEntryAssembly()!.GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); swaggerGenOptions.IncludeXmlComments(xmlPath, includeControllerXmlComments: true); });
方案2:自定义Schema过滤器忽略抽象基类
如果基类无实际业务属性,添加自定义过滤器让Swagger直接使用子类Schema:
public class IgnoreAbstractBaseRequestFilter : ISchemaFilter { public void Apply(OpenApiSchema schema, SchemaFilterContext context) { if (context.Type == typeof(BaseRequest)) { // 替换为具体子类的Schema定义 var mergeRequestSchema = context.SchemaRepository.Schemas[typeof(MergeRequest).Name]; schema.Properties = mergeRequestSchema.Properties; schema.Required = mergeRequestSchema.Required; } } } // 在Swagger配置中注册过滤器 services.AddSwaggerGen(swaggerGenOptions => { // ... 其他原有配置 swaggerGenOptions.SchemaFilter<IgnoreAbstractBaseRequestFilter>(); });
方案3:移除不必要的基类继承
如果BaseRequest没有任何属性或业务逻辑,直接简化参数类结构:
public class MergeRequest { }
验证
修改配置后重启应用,访问Swagger页面,确认接口文档正常生成,不再出现500错误。
内容的提问来源于stack exchange,提问作者VJAI

