如何配置NSwag让SwaggerUI的MediaType下拉框包含API版本号
解决NSwag SwaggerUI MediaType下拉框无API版本的问题
针对你使用MediaTypeApiVersionReader通过Accept头传递API版本的场景,需要调整NSwag的文档生成和SwaggerUI配置,让下拉框显示带版本号的媒体类型,具体步骤如下:
1. 确保API版本基础配置正确
先确认你的API版本ing配置已指定MediaTypeApiVersionReader,示例代码:
builder.Services.AddApiVersioning(options => { options.DefaultApiVersion = new ApiVersion(1, 0); options.AssumeDefaultVersionWhenUnspecified = true; options.ReportApiVersions = true; // 指定Accept头中的版本参数名(比如v=1.0) options.ApiVersionReader = new MediaTypeApiVersionReader("v"); }); // 添加API版本描述提供器,用于后续NSwag配置 builder.Services.AddVersionedApiExplorer(options => { options.GroupNameFormat = "'v'VVV"; options.SubstituteApiVersionInUrl = true; });
2. 为每个API版本配置NSwag文档
遍历所有API版本,为每个版本生成独立的Swagger文档,并强制文档中的Produces/Consumes使用带版本号的媒体类型:
var apiVersionDescriptionProvider = builder.Services.BuildServiceProvider() .GetRequiredService<IApiVersionDescriptionProvider>(); foreach (var description in apiVersionDescriptionProvider.ApiVersionDescriptions) { builder.Services.AddOpenApiDocument(settings => { // 绑定当前API版本到文档 settings.ApiVersion = description.ApiVersion.ToString(); settings.DocumentName = description.GroupName; settings.Title = $"你的API名称 {description.GroupName}"; settings.Version = description.ApiVersion.ToString(); // 设置默认的Produces/Consumes为带版本的媒体类型 var versionedMediaType = $"application/json;v={description.ApiVersion}"; settings.DefaultProduces = new[] { versionedMediaType }; settings.DefaultConsumes = new[] { versionedMediaType }; // 添加自定义处理器,确保每个接口操作都使用带版本的媒体类型 settings.OperationProcessors.Add(new ApiVersionOperationProcessor(description)); // 过滤仅包含当前版本的API接口 settings.DocumentProcessors.Add(new ApiVersionDocumentProcessor(description)); }); }
3. 实现自定义操作处理器(强制媒体类型带版本)
创建ApiVersionOperationProcessor类,确保每个接口的请求/响应媒体类型都带上版本号:
public class ApiVersionOperationProcessor : IOperationProcessor { private readonly ApiVersionDescription _apiVersionDescription; public ApiVersionOperationProcessor(ApiVersionDescription apiVersionDescription) { _apiVersionDescription = apiVersionDescription; } public bool Process(OperationProcessorContext context) { var versionedMediaType = $"application/json;v={_apiVersionDescription.ApiVersion}"; // 清空默认媒体类型,替换为带版本的类型 context.OperationDescription.Operation.Produces.Clear(); context.OperationDescription.Operation.Produces.Add(versionedMediaType); context.OperationDescription.Operation.Consumes.Clear(); context.OperationDescription.Operation.Consumes.Add(versionedMediaType); return true; } }
4. 配置SwaggerUI加载版本化文档
最后配置SwaggerUI,让它加载所有版本的文档,并自动识别每个文档对应的带版本媒体类型:
app.UseSwaggerUi3(settings => { settings.Path = "/swagger"; settings.DocumentPath = "/swagger/{documentName}/swagger.json"; // 添加所有版本的Swagger文档路由 foreach (var description in apiVersionDescriptionProvider.ApiVersionDescriptions) { settings.SwaggerRoutes.Add(new SwaggerUi3Route(description.GroupName, $"/swagger/{description.GroupName}/swagger.json")); } // 设置默认选中的文档(可选) settings.DefaultRoute = apiVersionDescriptionProvider.ApiVersionDescriptions .First(d => d.IsDefault).GroupName; });
完成以上配置后,SwaggerUI的MediaType下拉框会显示对应版本的媒体类型(比如application/json;v=1.0、application/json;v=2.0),选择后发起请求时会自动在Accept头中带上版本号,从而正确调用指定版本的API端点。
内容的提问来源于stack exchange,提问作者cdarrigo
相关产品推荐
相关产品推荐

