使用Swashbuckle 5.6时如何过滤Swagger schema中的冗余数据类型?
问题背景
使用Swashbuckle 5.6版本时,控制器中存在如下返回第三方基类的接口方法:
[ProducesResponseType(typeof(HealthCheckActionResult), (int)HttpStatusCode.OK)] public HealthCheckActionResult Get() { return new HealthCheckActionResult(healthCheckService, healthCheckOptions); }
接口上线后Swagger UI的Schema定义中出现大量CLR内部类型,Schema异常臃肿,页面加载、API测试时频繁卡顿。现有公开的Schema过滤方案未生效,且无权限修改第三方提供的HealthCheckActionResult类。
解决方案
以下三个方案均无需修改第三方类,可按需选择:
方案1:自定义类型映射(推荐)
直接为HealthCheckActionResult指定固定的Schema结构,阻断Swagger递归扫描其所有内部属性,完全不会生成冗余类型。在Startup.cs的AddSwaggerGen配置块中添加如下代码:services.AddSwaggerGen(c => { // 保留原有Swagger配置 // 按照接口实际返回的JSON结构配置Schema,可自行调整字段 c.MapType<HealthCheckActionResult>(() => new OpenApiSchema { Type = "object", Properties = new Dictionary<string, OpenApiSchema> { { "status", new OpenApiSchema { Type = "string", Description = "健康检查状态,可选值:Healthy/Unhealthy/Degraded" } }, { "description", new OpenApiSchema { Type = "string", Description = "健康检查详情描述" } } } }); });优先级最高,适配性强,单独针对该类型处理不会影响其他接口
方案2:批量过滤系统命名空间类型
自定义Schema过滤器,在生成阶段直接排除所有系统内置命名空间下的类型,批量清理冗余Schema。首先新增过滤器类:public class ExcludeSystemTypesSchemaFilter : ISchemaFilter { // 可自行扩展需要排除的命名空间前缀 private readonly List<string> _excludePrefixes = new List<string> { "System.", "Microsoft." }; public void Apply(OpenApiSchema schema, SchemaFilterContext context) { if (context.Type?.Namespace == null) return; if (_excludePrefixes.Any(p => context.Type.Namespace.StartsWith(p))) { context.SchemaRepository.Schemas.Remove(context.SchemaId); } } }再注册过滤器到Swagger配置中:
services.AddSwaggerGen(c => { // 保留原有Swagger配置 c.SchemaFilter<ExcludeSystemTypesSchemaFilter>(); });适合多接口存在同类冗余Schema问题的场景,一次配置全局生效
方案3:修改返回类型声明
如果已经明确接口实际返回的JSON结构对应的数据模型,直接修改ProducesResponseType的类型参数即可,Swagger会以指定的DTO为准生成Schema,不会扫描HealthCheckActionResult的内部结构:// 替换HealthCheckDto为你自定义的、和返回结构一致的DTO类 [ProducesResponseType(typeof(HealthCheckDto), (int)HttpStatusCode.OK)] public HealthCheckActionResult Get() { return new HealthCheckActionResult(healthCheckService, healthCheckOptions); }改造成本最低,无需调整全局Swagger配置
内容的提问来源于stack exchange,提问作者JustAMartin
相关产品推荐
相关产品推荐

