如何为Swashbuckle中泛型类的Schema设置专属format属性?
解决Swashbuckle.AspNetCore泛型类Schema Format自定义问题
问题本质是nameof(ResponseList<T>)在编译阶段只能获取类的原始名称"ResponseList",无法捕获运行时的泛型参数信息,因此需要通过自定义Schema过滤器动态生成带泛型参数标识的Format值。
实现步骤
1. 编写自定义Schema过滤器
创建实现ISchemaFilter的类,专门处理泛型类型的Format生成逻辑:
using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; using System; using System.Linq; public class GenericSchemaFormatFilter : ISchemaFilter { public void Apply(OpenApiSchema schema, SchemaFilterContext context) { var targetType = context.Type; // 仅处理泛型类型 if (!targetType.IsGenericType) return; // 获取泛型定义的基础名称(移除`1`这类泛型标记) var baseTypeName = targetType.GetGenericTypeDefinition().Name; baseTypeName = baseTypeName.Substring(0, baseTypeName.IndexOf('`')); // 拼接所有泛型参数的名称 var genericParamNames = string.Join("", targetType.GetGenericArguments().Select(t => t.Name)); // 设置最终的Format值 schema.Format = $"{baseTypeName}{genericParamNames}"; } }
2. 注册过滤器到Swagger配置
在项目的Swagger服务配置中添加这个自定义过滤器:
.NET 6+(Program.cs)
builder.Services.AddSwaggerGen(c => { // 其他Swagger配置项... c.SchemaFilter<GenericSchemaFormatFilter>(); });
.NET 5及以下(Startup.cs)
public void ConfigureServices(IServiceCollection services) { services.AddSwaggerGen(c => { // 其他Swagger配置项... c.SchemaFilter<GenericSchemaFormatFilter>(); }); }
3. 可选:兼容非泛型类的注解配置
如果非泛型类仍希望通过[SwaggerSchema(Format = nameof(...))]手动设置Format,可以修改过滤器逻辑,仅在未手动指定Format时处理泛型类型:
public void Apply(OpenApiSchema schema, SchemaFilterContext context) { var targetType = context.Type; // 已手动设置Format则跳过 if (!string.IsNullOrEmpty(schema.Format)) return; // 仅处理泛型类型 if (!targetType.IsGenericType) return; var baseTypeName = targetType.GetGenericTypeDefinition().Name; baseTypeName = baseTypeName.Substring(0, baseTypeName.IndexOf('`')); var genericParamNames = string.Join("", targetType.GetGenericArguments().Select(t => t.Name)); schema.Format = $"{baseTypeName}{genericParamNames}"; }
效果验证
配置完成后,生成的Swagger Schema将符合预期:
"ResponseList<User>": { "format": "ResponseListUser", "type": "object", ... }, "ResponseList<Product>": { "format": "ResponseListProduct", "type": "object", ... }
内容的提问来源于stack exchange,提问作者Karim Omrane
相关产品推荐
相关产品推荐

