在日常開發 webapi 時,我們往往會集成 swagger doc 進行 api 的文檔呈現,當api數量比較多的時候就會導致 swagger ui 上的 api 因為數量太多而顯得雜亂,今天教大家如何利用 GroupName 屬性來對 api 的 Controller 進行分組,然後利用 swa ...
在日常開發 webapi 時,我們往往會集成 swagger doc 進行 api 的文檔呈現,當api數量比較多的時候就會導致 swagger ui 上的 api 因為數量太多而顯得雜亂,今天教大家如何利用 GroupName 屬性來對 api 的 Controller 進行分組,然後利用 swagger ui 上的 Select a definition 切換功能進行多組 Controller 的切換。
首先進行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 網頁呈現如下
我們可以按照控制器的功能屬性或者業務屬性,將多個控制器分配到一個 Group。
上面講的方法需要對所有的控制器進行添加 [ApiExplorerSettings(GroupName = "xxxxx")] 屬性,下麵順便介紹一下如何通過文件的歸類對 控制器進行批量添加 GroupName
我們可以調整我們的控制器存放為文件夾,將同一個組的控制器放在一個文件夾中,示例如下圖
調整存放路徑之後,利用 vs 的 同步命名空間功能,選中項目,直接右擊 同步命名空間,就可以把所有控制器的命名空間都調整過來,命名空間的最後一節其實就是我們文件夾的名稱,也就是我們的 GroupName,如下:
然後我們可以利用 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 基礎框架項目,項目地址如下 https://github.com/berkerdong/NetEngine.git https://gitee.com/berkerdong/NetEngine.git