【问题标题】:How to stop default api vesion showing up in swagger document with NSwag in .Net Core?如何在 .Net Core 中使用 NSwag 阻止默认 api vesion 出现在 swagger 文档中?
【发布时间】:2021-06-21 10:36:34
【问题描述】:

在 .net 核心中通过以下方式修复 Api 版本控制后

            services.AddApiVersioning(options =>
            {
                options.AssumeDefaultVersionWhenUnspecified = true;
                options.DefaultApiVersion = new ApiVersion(1, 0);
                options.UseApiBehavior = false; //If true [ApiController] attribute required for versioning
            })
            .AddVersionedApiExplorer(options =>
            {
                options.GroupNameFormat = "'v'VVV";
                options.SubstituteApiVersionInUrl = true;
            });

我面临的下一个问题是让默认的 api 版本显示 swagger 文档。如下图所示。

有很多文章使用 swashbuckle 修复它,但是如何使用 NSwag 修复它?

【问题讨论】:

    标签: asp.net-core .net-core swashbuckle nswag api-versioning


    【解决方案1】:

    借助 NSwug,我们可以使用 DocumentProcessors 来过滤掉不需要的招摇路径。

    我用过下面的nuget包

    <PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="5.0.0" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer" Version="5.0.0" /> 
    <PackageReference Include="NSwag.AspNetCore" Version="13.9.4" />
    

    下面显示了我是如何注册它们并解决问题的

            public void ConfigureServices(IServiceCollection services)
        {
                ....
                
                services.AddApiVersioning(options =>
                {
                    options.AssumeDefaultVersionWhenUnspecified = true;
                    options.DefaultApiVersion = new ApiVersion(1, 0);
                })
                .AddVersionedApiExplorer(options =>
                {
                    options.GroupNameFormat = "'v'VVV";
                    options.SubstituteApiVersionInUrl = true;
                });
                
                services.AddSwaggerDocument(config =>
                {
                    SwaggerConfigure(config, "v1", true);
                });
    
                services.AddSwaggerDocument(config =>
                {
                    SwaggerConfigure(config, "v2", false);
                });
        }
    

    SwaggerConfigure 实现

            private void SwaggerConfigure(AspNetCoreOpenApiDocumentGeneratorSettings configure, string version, bool isDefaultVersion)
        {
            configure.DocumentName = version;
            configure.ApiGroupNames = new[] { version };
    
            if (isDefaultVersion)
            {
                configure.DocumentProcessors.Add(new RemoveVersionFromDefault(version));
            }
    
            configure.PostProcess = document =>
            {
                document.Info.Version = version;
                document.Info.Title = $"{GetApiTitle()} API";
            };
    
            configure.AllowNullableBodyParameters = false;
            configure.SerializerSettings = new JsonSerializerSettings();
        }
    

    DocumentProcessor 实现

        public class RemoveVersionFromDefault : IDocumentProcessor
        {
        private readonly string _defaultVersion;
    
        public RemoveVersionFromDefault(string defaultVersion)
        {
            _defaultVersion = defaultVersion;
        }
    
        public void Process(DocumentProcessorContext context)
        {
            var keys = new List<string>();
            foreach (var (key, value) in context.Document.Paths)
            {
                if (key.Contains($"/{_defaultVersion}/"))
                {
                    keys.Add(key);
                }
            }
    
            foreach (var key in keys)
            {
                context.Document.Paths.Remove(key);
            }
        }
    }
    

    就是这样。希望这对正在寻找与 NSwug 类似解决方案的人有所帮助

    【讨论】:

      【解决方案2】:

      有几种方法可以解决这种情况。另一种方法是创建并注册最后执行的自定义 IApiDescriptionProvider。从提供给IApiDescriptionProvider.OnProvidersExecuted 上下文的结果 ApiDescription 实例中,您可以找到您要查找的内容并从结果中删除描述符。在这种情况下,您希望删除与默认 API 版本与 API 版本参数匹配的描述符。

      这种方法有几个好处:

      1. 可以通过注入IOptions&lt;ApiVersioningOptions&gt;获取配置的默认API版本
      2. 您可以使用ApiDescriptor.GetApiVersion 扩展方法和仍然具有API 版本参数的过滤器描述符匹配API 版本。您可以硬编码名称或从步骤 1 中注入的 ApiVersioningOptions.RouteConstraintName 中获取它。没有 magic string 解析或匹配。
      3. 如果您在 Open API (Swagger) 文档生成器之间切换(例如 NSwag 到 Swashbuckle,反之亦然),则无需更改其他代码来解决这种情况

      旁白:评论:

      options.UseApiBehavior = false; //If true [ApiController] attribute required for versioning

      不太准确。你可能会得到你想要的结果,但还有更多的故事。这种行为和定制没有很好的记录,几乎没有人改变它。该行为实际上由IApiControllerSpecificationIApiControllerFilter 控制。默认过滤器实现只是贯穿所有已注册的规范,因此几乎没有理由更改它。每个规范都定义了控制器是否匹配。有一个与[ApiController] 匹配的开箱即用规范,但这不是唯一存在的规范(例如:OData 控制器)。 UseApiBehavior 选项存在的原因是因为在 [ApiController] 之前(在 2.1 中我认为),没有明确的方法来区分纯 UI 和纯 API 控制器。这确实激怒了一些混合使用这两种控制器的开发人员。相反,翻转硬开关以禁用可能会破坏想要该行为的开发人员。将值设置为 false 只会忽略所有过滤并恢复到 [ApiController] 之前的日子,这是在名为 API 行为 的功能增强中引入的。如果您决定这样做,新设计允许您替换或创建新规范。它可能不适用于您,但应该知道配置选项不是硬的onoff 用于匹配[ApiController] 和其他更复杂的控制器过滤是可能的。

      【讨论】:

      • 感谢@Chris 的输入和评论。确实提供了很多见解。
      • 我发现 options.UseApiBehavior = false;影响实际的招摇文档,因为它实际上删除了所有 api 行为。相反,我将 apicontroller 在程序集级别强制为 [assembly:ApiController],如提到的 strathweb.com/2019/01/…
      猜你喜欢
      • 2018-12-14
      • 2021-03-28
      • 2017-12-16
      • 2021-09-19
      • 1970-01-01
      • 2017-07-06
      • 1970-01-01
      • 1970-01-01
      • 2022-11-02
      相关资源
      最近更新 更多