3

.NET WebAPI 使用 GroupName 对 Controller 分组呈现 Swagger UI - 张晓栋

 2 years ago
source link: https://www.cnblogs.com/berkerdong/p/16520415.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

.NET WebAPI 使用 GroupName 对 Controller 分组呈现 Swagger UI

在日常开发 webapi 时,我们往往会集成 swagger doc 进行 api 的文档呈现,当api数量比较多的时候就会导致 swagger ui 上的 api 因为数量太多而显得杂乱,今天教大家如何利用 GroupName 属性来对 api 的 Controller 进行分组,然后利用 swagger ui 上的 Select a definition 切换功能进行多组 Controller 的切换。

1963085-20220726111538395-1405838628.png

首先进行swagger注册

            #region 注册 Swagger
            builder.Services.AddTransient<IConfigureOptions<SwaggerGenOptions>, SwaggerConfigureOptions>();

            builder.Services.AddSwaggerGen(options =>
            {
                options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, $"{typeof(Program).Assembly.GetName().Name}.xml"), true);

                var modelPrefix = Assembly.GetEntryAssembly()?.GetName().Name + ".Models.";
                options.SchemaGeneratorOptions = new SchemaGeneratorOptions { SchemaIdSelector = type => type.ToString()[(type.ToString().IndexOf("Models.") + 7)..].Replace(modelPrefix, "").Replace("`1", "").Replace("+", ".") };
            });
            #endregion

然后启用 swagger

            #region 启用 Swagger

            //启用中间件服务生成Swagger作为JSON端点
            app.UseSwagger();

            //启用中间件服务对swagger-ui,指定Swagger JSON端点
            app.UseSwaggerUI(options =>
            {
                var apiDescriptionGroups = app.Services.GetRequiredService<IApiDescriptionGroupCollectionProvider>().ApiDescriptionGroups.Items;
                foreach (var description in apiDescriptionGroups)
                {
                    options.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", description.GroupName);
                }
            });

            #endregion

这里用到了一个自定义的 Swagger Doc 生成配置

    public class SwaggerConfigureOptions : IConfigureOptions<SwaggerGenOptions>
    {
        private readonly IApiDescriptionGroupCollectionProvider provider;


        public SwaggerConfigureOptions(IApiDescriptionGroupCollectionProvider provider) => this.provider = provider;


        public void Configure(SwaggerGenOptions options)
        {
            foreach (var description in provider.ApiDescriptionGroups.Items)
            {
                options.SwaggerDoc(description.GroupName, null);
            }
        }

    }

这个方法的主要作用就是从 ApiDescriptionGroups 进行循环依次添加多个 Swagger Doc

然后关于本文目的的 swagger 配置就完成了。接下来就是对控制器进行分组标记的操作了。

关于对 Controller 进行 GroupName 分组,这里需要用到 ApiExplorerSettings 属性来标记 GroupName,并且同时修改 Route 信息,添加前缀,示例如下

    /// <summary>
    /// 系统访问授权模块
    /// </summary>
    [ApiExplorerSettings(GroupName = "Basic")]
    [Route("Basic/[controller]")]
    [ApiController]
    public class AuthorizeController : ControllerBase
    {

    }

这样就将 AuthorizeController 分到了 Basic 组,在 swagger ui 网页呈现如下

1963085-20220726113207070-1895579814.png

我们可以按照控制器的功能属性或者业务属性,将多个控制器分配到一个 Group。

上面讲的方法需要对所有的控制器进行添加 [ApiExplorerSettings(GroupName = "xxxxx")] 属性,下面顺便介绍一下如何通过文件的归类对 控制器进行批量添加 GroupName

我们可以调整我们的控制器存放为文件夹,将同一个组的控制器放在一个文件夹中,示例如下图

1963085-20220726113603466-2006636580.png

 调整存放路径之后,利用 vs 的 同步命名空间功能,选中项目,直接右击 同步命名空间,就可以把所有控制器的命名空间都调整过来,命名空间的最后一节其实就是我们文件夹的名称,也就是我们的 GroupName,如下:

1963085-20220726113800438-1868421664.png

 然后我们可以利用 IControllerModelConvention 在项目启动时获取控制器命名空间的最后一节的值,将他赋值到控制器的 [ApiExplorerSettings(GroupName = "xxxxx")] GroupName 属性,代码如下

    public class GroupNameConvention : IControllerModelConvention
    {
        public void Apply(ControllerModel controller)
        {
            var controllerNamespace = controller.ControllerType.Namespace;
            var groupName = controllerNamespace!.Split('.').LastOrDefault();
            controller.ApiExplorer.GroupName = groupName;
        }
    }

然后只要在项目启动时注入这个方法即可

            builder.Services.AddMvc(options =>
            {
                options.Conventions.Add(new GroupNameConvention());
            });

这样就完成了对 控制器 GroupName 的批量赋值,不过如果想要保持路由前缀和 GroupName 一致的话,还是需要自己手动的调整一下 控制器的路由前缀。

至此 .NET WebAPI 使用 GroupName 对 Controller 分组呈现 Swagger UI 就讲解完了,有任何不明白的,可以在文章下面评论或者私信我,欢迎大家积极的讨论交流,有兴趣的朋友可以关注我目前在维护的一个 .net 基础框架项目,项目地址如下

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK