近期一直在学习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枚举值,再进行判断,实现一个接口能够归为多个分组。