ASP.NET Core – Swagger API Versioning
前言
Versioning 会导致 Swagger 直接坏掉. 因为 1 个文档无法支持多个版本. 所以需要每一个版本做一个文档.
主要参考
Integrating ASP.NET Core Api Versions with Swagger UI
What every ASP.NET Core Web API project needs - Part 2 - API versioning and Swagger
Docs – aspnet-api-versioning(最新版本,上面的是旧版本的参考)
Stack Overflow – iServiceCollection' does not contain a definition for 'addVersionedApiExplorer'
安装 Versioning.ApiExplorer
dotnet add package Asp.Versioning.Mvc.ApiExplorer
Program.cs
var apiVersioningBuilder = builder.Services.AddApiVersioning(options => { options.AssumeDefaultVersionWhenUnspecified = true; options.DefaultApiVersion = new ApiVersion(1, 0); options.ReportApiVersions = true; }).AddMvc(); apiVersioningBuilder.AddApiExplorer(options => { options.GroupNameFormat = "'v'VVV"; options.SubstituteApiVersionInUrl = true; });
AddApiVersioning 后会返回一个 versioning builder,利用它来继续 setup Swagger 的部分。
做一个 ConfigureSwaggerOptions.cs
把之前的 XML, OpenApiInfo 放进去, 关键就是让它变成动态创建, 依赖 version.
using System.Reflection; using Asp.Versioning.ApiExplorer; using Microsoft.Extensions.Options; using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; namespace WebApi; public class ConfigureSwaggerOptions(IApiVersionDescriptionProvider provider) : IConfigureNamedOptions<SwaggerGenOptions> { private readonly IApiVersionDescriptionProvider provider = provider; public void Configure(SwaggerGenOptions options) { foreach (var description in provider.ApiVersionDescriptions) { options.SwaggerDoc(description.GroupName, CreateVersionInfo(description)); var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); options.IncludeXmlComments(xmlPath); } } public void Configure(string? name, SwaggerGenOptions options) { Configure(options); } private static OpenApiInfo CreateVersionInfo(ApiVersionDescription description) { var version = description.ApiVersion.ToString(); var info = new OpenApiInfo() { Title = "Project Web API", Version = $"v{version}", Description = $"DB&Project Web API version {version}", Contact = new OpenApiContact { Name = "Derrick Yam", Email = "hengkeat87@gmail.com", }, }; if (description.IsDeprecated) { info.Description += " This API version has been deprecated."; } return info; } }
配置
builder.Services.ConfigureOptions<ConfigureSwaggerOptions>();
最后是 UI, 需要注入 IApiVersionDescriptionProvider
app.UseSwaggerUI(options => { foreach (var description in app.Services.GetRequiredService<IApiVersionDescriptionProvider>().ApiVersionDescriptions) { options.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", $"Project Web API v{description.ApiVersion}"); options.DocExpansion(DocExpansion.None); } });
这样就可以了