我正在使用 Swashbuckle.AspNetCore 生成我的招摇文档,并且我正在使用ApiVersion对我的控制器进行版本控制。我的设置支持多个版本,这很好用。这意味着我可以在 Swagger UI 中选择一个版本,并且我为每个版本创建了一个 swagger 文档,其中只有相关的操作。
但是,我想重构 swagger 文档以便更好地利用 basepath 属性。
例如,让我使用为我的 API 版本 1 生成的 swagger 文档。在本文档中,所有路径都以 开头"/api/v1/..."
,生成的 swagger 文档中没有基本路径。但是,我想要的是,我的所有路径都以 开头"/..."
,并且生成的文档包含一个值为 的 basepath 属性"/api/v1"
。
我曾尝试创建一个 DocumentFilter,它让我很接近,但并非一直如此。没错,我可以访问该GroupName
属性(它包含版本字符串“v1”),但我的谓词显然失败了,因为值为swaggerDoc.Info.Version
“1.0”。这就是今天课程的样子:
public class SetBasePath : IDocumentFilter
{
public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
{
swaggerDoc.BasePath = $"/{context.ApiDescriptionsGroups.Items.Where(i => i.GroupName == swaggerDoc.Info.Version).Single().GroupName}";
}
}
然后我尝试了另一种方法,PreSerializeFilters
首先将基本路径添加到 swagger 文档中,然后再次将其从文档中的路径中删除。这也让我非常接近,但失败了,因为PreSerializeFilters
不是为每个 swagger 文档执行一次,而是一次(因此指定的最后一个基本路径将在所有生成的文档中使用)。这是我使用的代码PreSerializeFilters
:
app.UseSwagger(c =>
{
foreach (var description in apiVersionDescriptionProvider.ApiVersionDescriptions)
{
var basepath = $"/api/{description.GroupName}";
c.PreSerializeFilters.Add((swaggerDoc, httpReq) =>
{
swaggerDoc.Host = httpReq.Host.Value;
swaggerDoc.BasePath = basepath;
});
c.PreSerializeFilters.Add((swaggerDoc, httpReq) =>
{
IDictionary<string, PathItem> paths = new Dictionary<string, PathItem>();
foreach (var path in swaggerDoc.Paths)
{
paths.Add(path.Key.Replace(basepath, string.Empty, StringComparison.InvariantCulture), path.Value);
}
swaggerDoc.Paths = paths;
});
}
});
任何人都可以帮我走最后一英里,并按照我想要的方式进行吗?