Swashbuckle是否可将单个Swagger文档序列化为v2、其余为v3版本?
实现单个Swagger文档输出V2格式的方案
不需要全局开启SerializeAsV2,通过路由匹配单独给指定文档开启V2序列化配置即可,两种可行的实现方式如下:
方式1:通过Swagger预序列化过滤器实现
直接在默认Swagger配置中添加路由判断逻辑,代码侵入性更低:
var builder = WebApplication.CreateBuilder(args); // 注册多文档,和原有配置完全一致 builder.Services.AddSwaggerGen(options => { // 需要输出V2格式的文档 options.SwaggerDoc("legacy-v1", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "Legacy V1 API", Version = "v1" }); // 保持OpenAPI3格式的文档 options.SwaggerDoc("v2", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "V2 API", Version = "v2" }); }); var app = builder.Build(); app.UseSwagger(options => { options.PreSerializeFilters.Add((doc, req) => { // 匹配指定的文档名称,单独开启V2序列化 if (req.RouteValues.TryGetValue("documentName", out var docName) && docName.ToString() == "legacy-v1") { options.SerializeAsV2 = true; return; } options.SerializeAsV2 = false; }); }); app.UseSwaggerUI(options => { options.SwaggerEndpoint("/swagger/legacy-v1/swagger.json", "Legacy V1 API"); options.SwaggerEndpoint("/swagger/v2/swagger.json", "V2 API"); });
方式2:通过中间件分支单独配置
针对特定文档的路由路径单独挂载Swagger中间件,逻辑更清晰:
var builder = WebApplication.CreateBuilder(args); // 多文档注册和原有配置一致 builder.Services.AddSwaggerGen(options => { options.SwaggerDoc("legacy-v1", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "Legacy V1 API", Version = "v1" }); options.SwaggerDoc("v2", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "V2 API", Version = "v2" }); }); var app = builder.Build(); // 仅针对legacy-v1文档的请求开启V2序列化 app.MapWhen(ctx => ctx.Request.Path.StartsWithSegments("/swagger/legacy-v1"), builder => { builder.UseSwagger(opt => opt.SerializeAsV2 = true); }); // 其他文档走默认OpenAPI3配置 app.UseSwagger(); app.UseSwaggerUI(options => { options.SwaggerEndpoint("/swagger/legacy-v1/swagger.json", "Legacy V1 API"); options.SwaggerEndpoint("/swagger/v2/swagger.json", "V2 API"); });
验证方式:启动服务后分别访问两个文档的JSON地址,legacy-v1的返回值会包含"swagger": "2.0"字段,其余文档会包含"openapi": "3.x.x"字段,符合预期。
内容的提问来源于stack exchange,提问作者Josh Oakes
相关产品推荐
相关产品推荐

