通过Swashbuckle创建swagger文档的“最新”版本

问题描述 投票:0回答:1

我正在使用面向公众的API,使用Swashbuckle.AspNetCoreReDoc进行文档编写,并使用Microsoft.AspNetCore.Mvc.Versioning使用属性对控制器进行版本控制。

我们希望有一个醒目的文档来显示我们端点的所有最新版本,以使初次使用该API的人们更容易选择正确的版本。

我当前的尝试是创建一个'v0'并将该版本应用于所有最新版本的控制器。然后,我使用操作过滤器将“ v0”替换为最新版本:

public class LatestVersionOperationFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        var version = (context.MethodInfo.GetCustomAttributes<ApiVersionAttribute>()
                .Union(context.MethodInfo.DeclaringType.GetCustomAttributes<ApiVersionAttribute>())
                .SelectMany(x => x.Versions)
                .OrderByDescending(x => x.MajorVersion))
                .FirstOrDefault(x => x.MajorVersion != 0);
        if (version != null && context.ApiDescription.RelativePath.Contains("v0"))
        {
            context.ApiDescription.RelativePath = context.ApiDescription.RelativePath
                .Replace("v0", $"v{version.MajorVersion}");
        }
    }
}

这在大多数情况下都有效,但有时似乎没有效果,您最终得到了一堆带有'v0'的URL。过滤器运行了,但似乎并未反映在结果中招摇的文件。

是否有更好的方法来实现我们的目标?我尝试使用DocInclusionPredicate编写内容,但似乎无法获得想要的内容。

c# swashbuckle.aspnetcore
1个回答
0
投票

经过更多挖掘之后,我发现了这个旧问题:https://github.com/domaindrivendev/Swashbuckle/issues/361

我之前尝试过文档过滤器,但是感觉像走错了路。看到这个问题,我又走了一步,下面的内容正在为我们工作:

public class LatestVersionDocumentFilter : IDocumentFilter
{
    public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
    {
        foreach (var path in swaggerDoc.Paths.ToList())
        {
            if (!path.Key.Contains("v0"))
            {
                continue;
            }

            var apiDescription = context.ApiDescriptions.FirstOrDefault(x => x.RelativePath == path.Key.TrimStart('/'));
            if (apiDescription != null && apiDescription.TryGetMethodInfo(out var methodInfo))
            {
                var latestVersion = methodInfo.GetCustomAttributes<ApiVersionAttribute>()
                    .Union(methodInfo.DeclaringType.GetCustomAttributes<ApiVersionAttribute>())
                    .SelectMany(x => x.Versions)
                    .OrderByDescending(x => x.MajorVersion)
                    .FirstOrDefault(x => x.MajorVersion != 0);

                if (latestVersion != null)
                {
                    swaggerDoc.Paths.Remove(path.Key);
                    var latestUrl = path.Key.Replace("/v0/", $"/v{latestVersion.MajorVersion}/");
                    swaggerDoc.Paths.Add(latestUrl, path.Value);
                }
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.