開始之前,先介紹下swagger常用方法。
services.AddSwaggerGen //添加swagger中間件
c.SwaggerDoc //配置swagger文檔,也就是右上角的下拉框內容

c.IncludeXmlComments //引用程序集xml,用於加載出 備注信息等如圖

c.AddSecurityDefinition //添加授權驗證

c.DocInclusionPredicate //核心方法,指定分組被加載時 回調進入,也就是swagger右上角下拉框內的分組加載時
每一個分組加載時都會遍歷所有控制器的action 進入一次這個方法體內,返回true則 暴露 否則隱藏
1 c.DocInclusionPredicate((docName, apiDescription) => 2 { 3 //docName分組 的apiDescription 方法是否暴露 4 //return true 暴露 反之 隱藏 5 return true; 6 });
多分組步驟:
1.定義自定義標簽
1 public class ApiGroupAttribute : Attribute 2 { 3 public ApiGroupAttribute(params ApiGroupNames[] name) 4 { 5 GroupName = name; 6 } 7 8 public ApiGroupNames[] GroupName { get; set; } 9 10 } 11 12 public enum ApiGroupNames 13 { 14 [GroupInfo(Title = "登錄接口", Description = "用於登錄", Version = "20200828")] 15 Login, 16 } 17 18 public class GroupInfoAttribute : Attribute 19 { 20 public string Title { get; set; } 21 public string Version { get; set; } 22 public string Description { get; set; } 23 }
2.將標簽放在需要 分組的控制器或方法上
1 //可加載多個標簽,用於1個接口對應多個分組 2 [ApiGroup(ApiGroupNames.Login,ApiGroupNames.SubmitProgram)]
3.利用枚舉反射加載出每個分組的Doc
1 services.AddSwaggerGen(c => 2 { 3 //遍歷ApiGroupNames所有枚舉值生成接口文檔,Skip(1)是因為Enum第一個FieldInfo是內置的一個Int值 4 typeof(ApiGroupNames).GetFields().Skip(1).ToList().ForEach(f => 5 { 6 //獲取枚舉值上的特性 7 if (SwaggerEnumNames.Count(x => x.ToLower() == f.Name.ToLower()) > 0) 8 { 9 var info = f.GetCustomAttributes(typeof(GroupInfoAttribute), false).OfType<GroupInfoAttribute>().FirstOrDefault(); 10 c.SwaggerDoc(f.Name, new Microsoft.OpenApi.Models.OpenApiInfo 11 { 12 Title = info?.Title, 13 Version = info?.Version, 14 Description = info?.Description 15 }); 16 } 17 }); 18 }
4.DocInclusionPredicate 內寫核心邏輯代碼,利用反射的類進行判斷標簽值
1 //判斷接口歸於哪個分組 2 c.DocInclusionPredicate((docName, apiDescription) => 3 { 4 //反射拿到值 5 var actionlist = apiDescription.ActionDescriptor.EndpointMetadata.Where(x => x is ApiGroupAttribute); 6 if (actionlist.Count() > 0) 7 { 8 //判斷是否包含這個分組 9 var actionfilter = actionlist.FirstOrDefault() as ApiGroupAttribute; 10 return actionfilter.GroupName.Count(x => x.ToString() == docName) > 0; 11 } 12 return false; 13 } 14 });
如需要全部接口暴露並不用打標簽的,用SwaggerDoc單獨加載一個Doc用於顯示全部接口,在DocInclusionPredicate內加入 判斷 如果docName等於全部接口的DocName那么直接return true即可,可靈活運行,可配置在json 也可配置在數據庫等地方。用於指定分組是否暴露。以上加載Doc時, SwaggerEnumNames 就是需要暴露的分組列表,需要的自己定義來源
本文章參考 https://www.cnblogs.com/caijt/p/10739841.html 改寫的 一對多分組模式。需要一對一的可以參考
