0

我正在使用 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;
        });
    }
});

任何人都可以帮我走最后一英里,并按照我想要的方式进行吗?

4

1 回答 1

0

有几种方法可以使 ApiDescription 对象与 Swagger 文档版本匹配。您无法安全地反转 Swagger 文档版本;但是,由于您一开始就可以控制创建它,因此匹配起来并不难。您可能正在使用示例行为,如下所示:

new Info() { Version = description.ApiVersion.ToString() }

使用提供的扩展方法,您可以在文档过滤器中匹配它,如下所示:

public class SetBasePath : IDocumentFilter
{
    public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
    {
        var docVersion = swaggerDoc.Info.Version;
        var groupName = (from descriptionGroup in context.ApiDescriptionGroups.Items
                         from description in descriptionGroup.Items
                         let apiVersion = description.GetApiVersion().ToString()
                         where apiVersion == docVersion
                         select descriptionGroup.GroupName).First();

        swaggerDoc.BasePath = "/api/" + groupName;
    }
}

我希望这会有所帮助。

于 2018-04-14T01:08:13.870 回答