近期一直在學習Asp.net Core,微軟的文檔太難看,都是英文翻譯過來的,很不友好,感謝這個博客,從壹開始先後端分離【 .NET Core2.0 +Vue2.0 】,讓我入門了,剛學到這個Swagger時,我就有個需求,由於我以前寫過的系統是分了不一樣的模塊,模塊裏面再分控制器,不一樣模塊常常會有相同名稱的控制器,例如銷售中心模塊裏有個合同管理控制器,採購中心模塊裏也有個合同管理控制器,並且我一個系統接口可能得上百個,那若是都在一個頁面顯示的話,那也太多了,因此我想能不能把接口進行分組。css
在博客系統後面也有介紹到Swagger:API多版本控制,帶來的思考,還有網上查到的【dotNet Core】Swagger下簡單的給WebApi分組(我發現網上關於Asp.net Core的資料仍是比較少),再結合我本身的需求修改了一下。html
先說下個人想法:json
定義一個系統分組枚舉Enum,包含我係統全部的控制器分組(或者版本),而後再定義一個特性Attribute,能夠接收剛纔那個Enum值,在須要分組的控制器類上面定義特性Attribute,Swagger根據系統分組枚舉Enum的值進行分組,將特性Attribute的分組枚舉值同樣的歸爲同一個分組,沒有加特性Attribute的歸在無分組下,最終效果以下後端
下面是個人代碼,理解爲主,不用徹底按我寫的api
基礎Swagger的用法就不說的,具體可看 從壹開始先後端分離【 .NET Core2.0 +Vue2.0 】這個大師關於Swagger部分的教程,很是適合初級入門app
在項目建立一個目錄(ApiGroup),而後建立三個類,分別爲ApiGroupAttribute.cs(控制器特性),ApiGroupNames.css(系統分組枚舉),GroupInfoAttribute.cs(給系統分組枚舉值增長相關信息的特性,這個主要是用於在Swagger分組時可關聯Title,Version,Description值)前後端分離
ApiGroupAttribute.cs代碼以下ide
using Microsoft.AspNetCore.Mvc.ApiExplorer; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace ItSys.ApiGroup { /// <summary> /// 系統分組特性 /// </summary> public class ApiGroupAttribute : Attribute, IApiDescriptionGroupNameProvider { public ApiGroupAttribute(ApiGroupNames name) { GroupName = name.ToString(); } public string GroupName { get; set; } } }
ApiGroupNames.cs代碼以下post
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace ItSys.ApiGroup { /// <summary> /// 系統分組枚舉值 /// </summary> public enum ApiGroupNames { [GroupInfo(Title ="登陸認證",Description ="登陸認證相關接口",Version ="v1")] Auth, [GroupInfo(Title = "IT", Description = "登陸認證相關接口")] It, [GroupInfo(Title = "人力資源", Description = "登陸認證相關接口")] Hr, Cw } }
GroupInfoAttribute.cs代碼以下學習
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace ItSys.ApiGroup { /// <summary> /// 系統模塊枚舉註釋 /// </summary> public class GroupInfoAttribute : Attribute { public string Title { get; set; } public string Version { get; set; } public string Description { get; set; } } }
打開Startup.cs文件修改ConfigureServices方法(爲了方便查看,只列出關於Swagger分組的關鍵代碼)
public void ConfigureServices(IServiceCollection services) { #region Swagger services.AddSwaggerGen(options => { //遍歷ApiGroupNames全部枚舉值生成接口文檔,Skip(1)是由於Enum第一個FieldInfo是內置的一個Int值 typeof(ApiGroupNames).GetFields().Skip(1).ToList().ForEach(f => { //獲取枚舉值上的特性 var info = f.GetCustomAttributes(typeof(GroupInfoAttribute), false).OfType<GroupInfoAttribute>().FirstOrDefault(); options.SwaggerDoc(f.Name, new Swashbuckle.AspNetCore.Swagger.Info { Title = info?.Title, Version = info?.Version, Description = info?.Description }); }); //沒有加特性的分到這個NoGroup上 options.SwaggerDoc("NoGroup", new Swashbuckle.AspNetCore.Swagger.Info { Title = "無分組" }); //判斷接口歸於哪一個分組 options.DocInclusionPredicate((docName, apiDescription) => { if (docName == "NoGroup") { //當分組爲NoGroup時,只要沒加特性的都屬於這個組 return string.IsNullOrEmpty(apiDescription.GroupName); } else { return apiDescription.GroupName == docName; } }); }
修改Configure方法
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { #region Swagger app.UseSwagger(); app.UseSwaggerUI(options => { //遍歷ApiGroupNames全部枚舉值生成接口文檔,Skip(1)是由於Enum第一個FieldInfo是內置的一個Int值 typeof(ApiGroupNames).GetFields().Skip(1).ToList().ForEach(f => { //獲取枚舉值上的特性 var info = f.GetCustomAttributes(typeof(GroupInfoAttribute), false).OfType<GroupInfoAttribute>().FirstOrDefault(); options.SwaggerEndpoint($"/swagger/{f.Name}/swagger.json", info != null ? info.Title : f.Name); }); options.SwaggerEndpoint("/swagger/NoGroup/swagger.json", "無分組"); }); #endregion }
而後你F6生成一下,沒出錯的話,就Ctrl+F5看看,正常的話就會在Swagger右上角看到分組了。
在你須要進行分組的控制器上加上這個分組就ok了
目前是一個接口只歸爲一個分組,但可能實際中有些公用接口,會出如今多個分組模塊裏的,那能夠將ApiGroupAttribute增長一個string[]或ApiGroupNames[]屬性,接收多個枚舉值,或者定義多個ApiGroupAttribute特性,不過在ConfigureServices裏的Swagger的DocInclusionPredicate分組過濾方法裏,就不能單判斷GroupName參數了,能夠利用參數ApiDescription反射得出接口控制器上的ApiGroupAttribute特性,獲取全部的ApiGroupNames枚舉值,再進行判斷,實現一個接口能夠歸爲多個分組。