【发布时间】:2018-09-14 06:17:57
【问题描述】:
我正在使用 Swashbuckle.AspNetCore 来生成我的招摇文档,并且我正在使用 ApiVersion 来对我的控制器进行版本控制。我的设置支持多个版本,这很好用。这意味着我可以在 Swagger UI 中选择一个版本,并且我为每个版本创建了一个 swagger 文档,其中只有相关的操作。
但是,我想重构 swagger 文档以便更好地利用 basepath-property。
作为示例,让我使用为我的 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;
});
}
});
谁能帮我走最后一英里,并按照我想要的方式进行工作?
【问题讨论】:
-
你的项目在 GitHub 上吗?
-
不,抱歉。但是 aspnet-api-versioning 有一些示例项目可以作为起点,例如这个:github.com/Microsoft/aspnet-api-versioning/tree/master/samples/…
标签: asp.net-core swagger asp.net-core-webapi swashbuckle api-versioning