近期一直在学习Asp.net Core,微软的文档太难看,都是英文翻译过来的,很不友好,感谢这个博客,从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】,让我入门了,刚学到这个Swagger时,我就有个需求,因为我之前写过的系统是分了不同的模块,模块里面再分控制器,不同模块经常会有相同名称的控制器,例如销售中心模块里有个合同管理控制器,采购中心模块里也有个合同管理控制器,而且我一个系统接口可能得上百个,那如果都在一个页面显示的话,那也太多了,所以我想能不能把接口进行分组。

在博客系统后面也有介绍到Swagger:API多版本控制,带来的思考,还有网上查到的【dotNet Core】Swagger下简单的给WebApi分组(我发现网上关于Asp.net Core的资料还是比较少),再结合我自己的需求修改了一下。

先说下我的想法:

定义一个系统分组枚举Enum,包含我系统所有的控制器分组(或者版本),然后再定义一个特性Attribute,可以接收刚才那个Enum值,在需要分组的控制器类上面定义特性Attribute,Swagger根据系统分组枚举Enum的值进行分组,将特性Attribute的分组枚举值一样的归为同一个分组,没有加特性Attribute的归在无分组下,最终效果如下

下面是我的代码,理解为主,不用完全按我写的

基础Swagger的用法就不说的,具体可看 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】这个大师关于Swagger部分的教程,非常适合初级入门

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

ApiGroupAttribute.cs代码如下

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代码如下

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().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().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枚举值,再进行判断,实现一个接口可以归为多个分组。

Asp.net Core的Swagger接口根据模块、版本分组的更多相关文章

  1. .net core的Swagger接口文档使用教程(二):NSwag

    上一篇介绍了Swashbuckle ,地址:.net core的Swagger接口文档使用教程(一):Swashbuckle 讲的东西还挺多,怎奈微软还推荐了一个NSwag,那就继续写吧! 但是和Sw ...

  2. asp.net core 使用 swagger 生成接口文档

    参考地址:http://www.cnblogs.com/daxnet/p/6181366.html http://www.jianshu.com/p/fa5a9b76f3ed 微软参考文档:https ...

  3. Asp.Net Core配置Swagger

    本文主要参考:Using Swagger with ASP.net Core 1.创建WebApi项目 本文使用ASP.Net Core Web API项目模板演示Swagger到使用,首先创建Web ...

  4. Asp.Net Core WebApi (Swagger+EF Core/Code First)

    Swagger简介: Swagger™的目标是为REST APIs 定义一个标准的,与语言无关的接口,使人和计算机在看不到源码或者看不到文档或者不能通过网络流量检测的情况下能发现和理解各种服务的功能. ...

  5. ASP.NET CORE API Swagger+IdentityServer4授权验证

    简介 本来不想写这篇博文,但在网上找到的文章博客都没有完整配置信息,所以这里记录下. 不了解IdentityServer4的可以看看我之前写的入门博文 Swagger 官方演示地址 源码地址 配置Id ...

  6. Asp.Net Core集成Swagger

    工作中一个公司会有很多个项目,项目之间的交互经常需要编写 API 来实现,但是编写文档是一件繁琐耗时的工作,并且随着 API 的迭代,每次都需要去更新维护接口文档,很多时候由于忘记或者人员交替的愿意造 ...

  7. asp.net core 集成swagger ui

    什么是Swagger? 说swagger 之前,我们先说一下OpenApi 规范. OpenApi 是一种和语言无关的用于描述RESTAPIs 接口功能的一种规范,对RESTAPIs 接口的描述包括: ...

  8. ASP.NET Core 奇技淫巧之接口代理转发

    前言 先讲讲本文的开发背景吧.. 在如今前后端分离的大背景下,咱的客户又有要求啦~ 要前后端分离~ 然因为种种原因..没办法用用纯前端的框架(其实是学习成本高,又没钱请前端开发人员)... 所以最终决 ...

  9. 发布自己的第一版asp.net core的RESTful接口程序

    使用window开发一个简单的asp.net Core的RESTfull程序,网上很多,这里不说,我是直接使用IDE自己生成的项目来发布的.没有修改过主要代码.在IDE里发布到本地目录,得到类似文件 ...

随机推荐

  1. Spring Boot中使用Actuator的/info端点输出Git版本信息

    对于Spring Boot的Actuator模块相信大家已经不陌生了,尤其对于其中的/health./metrics等强大端点已经不陌生(如您还不了解Actuator模块,建议先阅读<Sprin ...

  2. difference between collection and association mapping in mybatis 3

    Mybatis处理“一对多”的关系时,需要用到associasion元素.处理”多对一“用collection元素来实现(这两个元素在之前mapper文件中提到过). 本例子中,假设一名User可以有 ...

  3. MongoDB中文档操作(二)

    一.插入文档  1.db.集合名.insert()   插入一个:db.user.insert({name:"Join",age:13,address:"beijing& ...

  4. python中用locust做简单的压力测试

    验证导入包成功 首先导入locust模块,百度一下导入方法很多,就不多说了 验证导入成功或失败,在终端中(windows中是cmd)输入:locust --help 导入成功后会出现如下界面: 编辑运 ...

  5. 剑指offer(javascript实现)

    1.二维数组中的查找 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. funct ...

  6. C++中的内联函数和C中的宏定义的区别

    在C++中内联函数: 内联函数即是在函数的声明和和定义前面加上“inline”关键字,内联函数和常规函数一样,都是按照值来传递参数的,如果参数为表达式,如4.5+7.5,则函数将传递表达式的值(这里为 ...

  7. 【bzoj 3131】[Sdoi2013]淘金

    Description 小Z在玩一个叫做<淘金者>的游戏.游戏的世界是一个二维坐标.X轴.Y轴坐标范围均为1..N.初始的时候,所有的整数坐标点上均有一块金子,共N*N块.    一阵风吹 ...

  8. bzoj4904 [Ctsc2017]最长上升子序列

    我们发现他让求的东西很奇怪,于是通过某D开头定理,我们转化为前m位的序列用k个不上升子序列最多能覆盖多少.数据范围小的时候可以网络流做,但是这道题显然不支持网络流的复杂度.然后有一个奇怪的东西叫杨氏矩 ...

  9. PCB设计流程

    一般PCB基本设计流程如下:前期准备->PCB结构设计->PCB布局->布线->布线优化和丝印->网络和DRC检查和结构检查->制版. 第一.前期准备. 这包括准备 ...

  10. Universal-Image-Loader源码解解析---display过程 + 获取bitmap过程

    Universal-Image-Loader在github上的地址:https://github.com/nostra13/Android-Universal-Image-Loader 它的基本使用请 ...