解决方案是在 swagger setter 中手动检查版本。就我而言,我还添加了支持的版本列表。
所以你必须在 Startup.cs 添加这个:
private readonly string[] supportedVersions = new string[] { "1", "2" };
public void ConfigureServices(IServiceCollection services)
{
...
services.AddApiVersioning();
services.AddSwaggerGen(c =>
{
c.DocInclusionPredicate((docName, apiDesc) =>
{
var metadata = apiDesc.ActionDescriptor.EndpointMetadata;
var apiVersionModel = metadata.Where(x => x.GetType() == typeof(ApiVersionAttribute)).Cast<ApiVersionAttribute>();
var supportedVersions = metadata.Where(x => x.GetType() == typeof(MapToApiVersionAttribute)).Cast<MapToApiVersionAttribute>();
if (apiVersionModel.IsNullOrEmpty() || supportedVersions.IsNullOrEmpty())
{
return false;
}
var apiVersions = apiVersionModel.SelectMany(x => x.Versions.Select(y => y.MajorVersion));
var versions = supportedVersions.SelectMany(x => x.Versions.Select(y => y.MajorVersion));
return apiVersions.Any(v => $"v{v.ToString()}" == docName) && versions.Any(v => $"v{v.ToString()}" == docName);
});
c.DocumentFilter<ReplaceVersionWithExactValueInPathFilter>();
c.OperationFilter<RemoveVersionParameterFilter>();
c.EnableAnnotations();
supportedVersions.ForEach(sv =>
{
c.SwaggerDoc($"v{sv}", new OpenApiInfo()
{
Version = $"v{sv}",
Title = $"API v{ sv }",
Description = "My web api",
});
});
var baseDirectory = AppContext.BaseDirectory;
var xmlFiles = Directory.EnumerateFiles(baseDirectory, "*.xml");
xmlFiles.ForEach(x => c.IncludeXmlComments(x));
});
...
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseSwaggerUI(c =>
{
supportedVersions.ForEach(sv =>
{
c.SwaggerEndpoint($"/swagger/v{sv}/swagger.json", $"My api v{sv}");
});
});
}
和分隔文件两种方法以避免在 UI 中将版本显示为参数。否则,您将看到带有版本参数而不是版本本身的端点。
public class RemoveVersionParameterFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
var versionParameter = operation.Parameters.FirstOrDefault(p => p.Name == "version");
if (versionParameter == default(OpenApiParameter)) return;
var parameters = operation.Parameters.ToList();
operation.Parameters.Remove(versionParameter);
}
}
public class ReplaceVersionWithExactValueInPathFilter : IDocumentFilter
{
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
{
var paths = new OpenApiPaths();
foreach (var path in swaggerDoc.Paths)
{
paths.Add(path.Key.Replace("v{version}", swaggerDoc.Info.Version), path.Value);
}
swaggerDoc.Paths = paths;
}
}