.NET Core Swagger 的分组使, 以及相同Action能被多个分组公用,同时加载出尚未分组的数据出来

  • A+
所属分类:.NET技术
摘要

1.本文章参考(https://www.cnblogs.com/caijt/p/10739841.html) 改写的 一对多分组模式。需要一对一的可以参考

1.本文章参考(https://www.cnblogs.com/caijt/p/10739841.html)改写的 一对多分组模式。需要一对一的可以参考

 

2.本文主要讲的是 一对多 分组公用, 同时把尚未分组的加载出来

 

3.效果演示GIF图:

 

.NET Core Swagger 的分组使, 以及相同Action能被多个分组公用,同时加载出尚未分组的数据出来

 

 

具体操作代码如下:

1.在项目创建一个目录(ApiGroup),然后创建三个类,分别为ApiGroupAttribute.cs(控制器特性),ApiGroupNames.css(系统分组枚举),GroupInfoAttribute.cs(给系统分组枚举值增加相关信息的特性,这个主要是用于在Swagger分组时可关联Title,Version,Description值)

 

.NET Core Swagger 的分组使, 以及相同Action能被多个分组公用,同时加载出尚未分组的数据出来

 

 

 

 

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右上角看到分组了。

.NET Core Swagger 的分组使, 以及相同Action能被多个分组公用,同时加载出尚未分组的数据出来

 

 

 

 

 

 

 *********************具体在 WeatherForecastController 里面的使用***************

1.单个Action特性 [ApiGroup(ApiGroupNames.Config)]

.NET Core Swagger 的分组使, 以及相同Action能被多个分组公用,同时加载出尚未分组的数据出来

 

 

 

2.多个Action特性 [ApiGroup(ApiGroupNames.Login,ApiGroupNames.It)]

.NET Core Swagger 的分组使, 以及相同Action能被多个分组公用,同时加载出尚未分组的数据出来

 

 

 

..............

具体详细的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 ----------------------------------

 

有疑问意见等,欢迎大家讨论.......