.NET Core Swagger 的分組使, 以及相同Action能被多個分組公用,同時加載出尚未分組的數據出來
1.本文章參考(https://www.cnblogs.com/caijt/p/10739841.html)改寫的 一對多分組模式。需要一對一的可以參考
2.本文主要講的是 一對多 分組公用, 同時把尚未分組的加載出來
3.效果演示GIF圖:
具體操作代碼如下:
1.在項目創建一個目錄(ApiGroup),然后創建三個類,分別為ApiGroupAttribute.cs(控制器特性),ApiGroupNames.css(系統分組枚舉),GroupInfoAttribute.cs(給系統分組枚舉值增加相關信息的特性,這個主要是用於在Swagger分組時可關聯Title,Version,Description值)
ApiGroupAttribute.cs代碼如下
/// <summary> /// 系統分組特性 /// </summary> public class ApiGroupAttribute : Attribute { public ApiGroupAttribute(params ApiGroupNames[] name) { GroupName = name; } public ApiGroupNames[] GroupName { get; set; } }
ApiGroupNames.cs代碼如下
/// <summary> /// 系統分組枚舉值 /// </summary> public enum ApiGroupNames { [GroupInfo(Title = "All", Description = "All接口", Version = "")] All = 0, [GroupInfo(Title = "尚未分組", Description = "尚未分組相關接口", Version = "")] NoGroup = 1, [GroupInfo(Title = "登錄認證", Description = "登錄認證相關接口", Version = "")] Login = 2, [GroupInfo(Title = "IT", Description = "登錄認證相關接口", Version = "")] It = 3, [GroupInfo(Title = "人力資源", Description = "登錄認證相關接口", Version = "")] Hr = 4, [GroupInfo(Title = "系統配置", Description = "系統配置相關接口", Version = "")] Config = 5 }
GroupInfoAttribute.cs代碼如下
public class GroupInfoAttribute : Attribute { public string Title { get; set; } public string Version { get; set; } public string Description { get; set; } }
******** 打開Startup.cs文件修改ConfigureServices方法(為了方便查看,只列出關於Swagger分組的關鍵代碼)*************
//1.0 ConfigureServices 里面swagger 的設置
#region swagger var openApiInfo = new OpenApiInfo { Version = "v1", Title = "WebApi", Description = "A simple example ASP.NET Core Web API", TermsOfService = new Uri("https://www.cnblogs.com/goodluckily/"), Contact = new OpenApiContact { Name = "雨太陽", Email = string.Empty, Url = new Uri("https://www.cnblogs.com/goodluckily/") }, License = new OpenApiLicense { Name = "許可證名字", Url = new Uri("https://www.cnblogs.com/goodluckily/") } }; services.AddSwaggerGen(c => { #region 分組方案二 //遍歷ApiGroupNames所有枚舉值生成接口文檔,Skip(1)是因為Enum第一個FieldInfo是內置的一個Int值 typeof(ApiGroupNames).GetFields().Skip(1).ToList().ForEach(f => { //獲取枚舉值上的特性 var info = f.GetCustomAttributes(typeof(GroupInfoAttribute), false).OfType<GroupInfoAttribute>().FirstOrDefault(); openApiInfo.Title = info?.Title; openApiInfo.Version = info?.Version; openApiInfo.Description = info?.Description; c.SwaggerDoc(f.Name, openApiInfo); }); //判斷接口歸於哪個分組 c.DocInclusionPredicate((docName, apiDescription) => { if (!apiDescription.TryGetMethodInfo(out MethodInfo method)) return false; //1.全部接口 if (docName == "All") return true; //反射拿到控制器分組特性下的值 var actionlist = apiDescription.ActionDescriptor.EndpointMetadata.FirstOrDefault(x => x is ApiGroupAttribute); //2.得到尚未分組的接口*************** if (docName == "NoGroup") return actionlist == null ? true : false; //3.加載對應已經分好組的接口 if (actionlist != null) { //判斷是否包含這個分組 var actionfilter = actionlist as ApiGroupAttribute; return actionfilter.GroupName.Any(x => x.ToString().Trim() == docName); } return false; }); #endregion //添加授權 //認證方式,此方式為全局添加 var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); c.IncludeXmlComments(xmlPath, true); }); #endregion
2.0 Configure 里面swagger 的設置
#region Swagger app.UseSwagger(); app.UseSwaggerUI(c => { c.RoutePrefix = "swagger"; #region 分組方案二 //遍歷ApiGroupNames所有枚舉值生成接口文檔,Skip(1)是因為Enum第一個FieldInfo是內置的一個Int值 typeof(ApiGroupNames).GetFields().Skip(1).ToList().ForEach(f => { //獲取枚舉值上的特性 var info = f.GetCustomAttributes(typeof(GroupInfoAttribute), false).OfType<GroupInfoAttribute>().FirstOrDefault(); c.SwaggerEndpoint($"/swagger/{f.Name}/swagger.json", info != null ? info.Title : f.Name); }); #endregion //swagger 默認折疊 //c.DocExpansion(Swashbuckle.AspNetCore.SwaggerUI.DocExpansion.None); //MiniProfiler用的 c.IndexStream = () => GetType().GetTypeInfo().Assembly.GetManifestResourceStream("WebApi.index.html"); }); #endregion
然后你F6生成一下,沒出錯的話,就Ctrl+F5看看,正常的話就會在Swagger右上角看到分組了。
*********************具體在 WeatherForecastController 里面的使用***************
1.單個Action特性 [ApiGroup(ApiGroupNames.Config)]
2.多個Action特性 [ApiGroup(ApiGroupNames.Login,ApiGroupNames.It)]
..............
具體詳細的Controller代碼如下
[ApiController] [Route("[controller]")] public class WeatherForecastController : Controller { private readonly ILogger<WeatherForecastController> _logger; private readonly IHttpContextAccessor _accessor; public WeatherForecastController(ILogger<WeatherForecastController> logger, IHttpContextAccessor accessor) { _logger = logger; _accessor = accessor; } /// <summary> /// 多分組共用請求 /// </summary> /// <returns></returns> //[ProducesResponseType(201)] //[ProducesResponseType(400)] [HttpGet("getLoginAndIT")] [ApiGroup(ApiGroupNames.Login,ApiGroupNames.It)] public IActionResult GetLoginAndIT() { return Json("GetLoginAndIT ok"); } [HttpGet("getConfig")] [ApiGroup(ApiGroupNames.Config)] public IActionResult GetConfig() { return Json("Config ok"); } [HttpGet("getHr")] [ApiGroup(ApiGroupNames.Hr)] public IActionResult GetHr() { return Json("Hr ok"); } [HttpGet("getIt")] [ApiGroup(ApiGroupNames.It)] public IActionResult GetIt() { return Json("GetIt ok"); } /// <summary> /// 獲取Miniprofiler Index的 Script (尚未分組的) /// </summary> /// <returns></returns> [HttpGet("getMiniprofilerScript")] public IActionResult getMiniprofilerScript() { var htmlstr = MiniProfiler.Current.RenderIncludes(_accessor.HttpContext); var script = htmlstr.Value; return Json(script); } }
轉載,請注明原文出處
-----------至此結束 end ----------------------------------
有疑問意見等,歡迎大家討論.......