基于 abp vNext 和 .NET Core 开发博客项目 - 再说Swagger,分组、描述、小绿锁
在开始本篇正文之前,解决一个 @疯疯过 指出的错误,再次感谢指正。

步骤如下:
- 删掉
.Domain.Shared层中的项目引用,添加nuget依赖包Volo.Abp.Identity.Domain.Shared,可以使用命令:Install-Package Volo.Abp.Identity.Domain.Shared - 在
.Domain层中引用项目.Domain.Shared,在模块类中添加依赖typeof(MeowvBlogDomainSharedModule) - 将
.EntityFrameworkCore层中的引用项目.Domain.Shared改成.Domain。

上一篇文章(https://www.cnblogs.com/meowv/p/12924409.html)完成了对API返回模型的封装,紧接着我打算继续来折腾一下Swagger,之前的文章中已经简单用起了Swagger,本篇还是围绕它让其发挥更高的更多的价值。
当我们的项目不断壮大,API持续增多,这时如果想要快速准确定位到某个API可能不是那么容易,需要翻半天才能找对我们的API。于是对Swagger API文档分组和详细的文档描述就有必要了,就本项目而言,博客系统可以分组为:博客前台接口、博客后台接口、其它公共接口、JWT认证授权接口。
其中,博客后台组中的接口需要授权后才可以调用,需要授权那么就涉及到身份验证,在这里准备采用JWT(JSON WEB TOKEN)的方式进行。
分组
对Swagger进行分组很简单,在.Swagger层中的扩展方法AddSwagger(this IServiceCollection services)中多次调用options.SwaggerDoc(...)即可,像这样
...
options.SwaggerDoc("v1", new OpenApiInfo
{
Version = "1.0.0",
Title = "我的接口啊1",
Description = "接口描述1"
});
options.SwaggerDoc("v2", new OpenApiInfo
{
Version = "1.0.0",
Title = "我的接口啊2",
Description = "接口描述2"
});
...
...
不过这样显得有点low,然后可以转变一下思路使用遍历的方式进行。options.SwaggerDoc(...)接收两个参数:string name, OpenApiInfo info。
name:可以理解为当前分组的前缀;OpenApiInfo:有许多可配置的参数,在这里我只用到三个,Version、Title、Description。
要注意,当在AddSwagger(...)中调用完后,还需要在我们的扩展方法UseSwaggerUI(this IApplicationBuilder app)中options.SwaggerEndpoint()使用它,同样的也用遍历的方法。它接收的的参数:string url, string name。
url:这里的url要与前面配置的name参数对应。
name:我们自定义显示的分组名称。
于是可以直接在扩展方法中新建一个内部类:SwaggerApiInfo
internal class SwaggerApiInfo
{
/// <summary>
/// URL前缀
/// </summary>
public string UrlPrefix { get; set; }
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// <see cref="Microsoft.OpenApi.Models.OpenApiInfo"/>
/// </summary>
public OpenApiInfo OpenApiInfo { get; set; }
}
然后新建一个List<SwaggerApiInfo>手动为其初始化一些值。
...
/// <summary>
/// Swagger分组信息,将进行遍历使用
/// </summary>
private static readonly List<SwaggerApiInfo> ApiInfos = new List<SwaggerApiInfo>()
{
new SwaggerApiInfo
{
UrlPrefix = Grouping.GroupName_v1,
Name = "博客前台接口",
OpenApiInfo = new OpenApiInfo
{
Version = version,
Title = "阿星Plus - 博客前台接口",
Description = description
}
},
new SwaggerApiInfo
{
UrlPrefix = Grouping.GroupName_v2,
Name = "博客后台接口",
OpenApiInfo = new OpenApiInfo
{
Version = version,
Title = "阿星Plus - 博客后台接口",
Description = description
}
},
new SwaggerApiInfo
{
UrlPrefix = Grouping.GroupName_v3,
Name = "通用公共接口",
OpenApiInfo = new OpenApiInfo
{
Version = version,
Title = "阿星Plus - 通用公共接口",
Description = description
}
},
new SwaggerApiInfo
{
UrlPrefix = Grouping.GroupName_v4,
Name = "JWT授权接口",
OpenApiInfo = new OpenApiInfo
{
Version = version,
Title = "阿星Plus - JWT授权接口",
Description = description
}
}
};
...
version:我们将其配置在appsettings.json中,做到动态可以修改。
//AppSettings.cs
...
/// <summary>
/// ApiVersion
/// </summary>
public static string ApiVersion => _config["ApiVersion"];
...
//appsettings.json
{
...
"ApiVersion": "1.0.0"
...
}
description:因为多次使用,就定义一个变量,内容自拟主要是一些介绍性的描述,将在Swagger界面进行显示。
UrlPrefix:分别为,v1,v2,v3,v4。在Domain.Shared层中为其定义好常量
//MeowvBlogConsts.cs
...
/// <summary>
/// 分组
/// </summary>
public static class Grouping
{
/// <summary>
/// 博客前台接口组
/// </summary>
public const string GroupName_v1 = "v1";
/// <summary>
/// 博客后台接口组
/// </summary>
public const string GroupName_v2 = "v2";
/// <summary>
/// 其他通用接口组
/// </summary>
public const string GroupName_v3 = "v3";
/// <summary>
/// JWT授权接口组
/// </summary>
public const string GroupName_v4 = "v4";
}
...
现在修改扩展方法AddSwagger(...),遍历List<SwaggerApiInfo>。
...
public static IServiceCollection AddSwagger(this IServiceCollection services)
{
return services.AddSwaggerGen(options =>
{
//options.SwaggerDoc("v1", new OpenApiInfo
//{
// Version = "1.0.0",
// Title = "我的接口啊",
// Description = "接口描述"
//});
// 遍历并应用Swagger分组信息
ApiInfos.ForEach(x =>
{
options.SwaggerDoc(x.UrlPrefix, x.OpenApiInfo);
});
...
});
}
...
在扩展方法UseSwaggerUI(...)使用,通用也需要遍历。
...
// 遍历分组信息,生成Json
ApiInfos.ForEach(x =>
{
options.SwaggerEndpoint($"/swagger/{x.UrlPrefix}/swagger.json", x.Name);
});
...
细心的同学可以发现,我们前几篇文章打开Swagger文档的时候都是需要手动更改URL地址:.../swagger才能正确进入,其实Swagger是支持配置路由的。同时咱们也将页面Title也给改了吧。看下面UseSwaggerUI(...)完整代码:
...
/// <summary>
/// UseSwaggerUI
/// </summary>
/// <param name="app"></param>
public static void UseSwaggerUI(this IApplicationBuilder app)
{
app.UseSwaggerUI(options =>
{
// 遍历分组信息,生成Json
ApiInfos.ForEach(x =>
{
options.SwaggerEndpoint($"/swagger/{x.UrlPrefix}/swagger.json", x.Name);
});
// 模型的默认扩展深度,设置为 -1 完全隐藏模型
options.DefaultModelsExpandDepth(-1);
// API文档仅展开标记
options.DocExpansion(DocExpansion.List);
// API前缀设置为空
options.RoutePrefix = string.Empty;
// API页面Title
options.DocumentTitle = "
基于 abp vNext 和 .NET Core 开发博客项目 - 再说Swagger,分组、描述、小绿锁的更多相关文章
- 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(一)
系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(二)
系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(三)
系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(四)
系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(五)
系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(一)
系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(二)
系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(三)
系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(四)
系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...
随机推荐
- 利用python画出动态高优先权优先调度
之前写过一个文章. 利用python画出SJF调度图 动态高度优先权优先调度 动态优先权调度算法,以就绪队列中各个进程的优先权作为进程调度的依据.各个进程的优先权在创建进程时所赋予,随着进程的推进或其 ...
- hdu_2391 Filthy Rich DP
Filthy Rich Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- 一款被大厂选用的 Hexo 博客主题
首先这是一篇自吹自擂的文章,主题是由多位非前端程序员共同开发,目前经过一年半的迭代已经到达 v1.8.0 版本,并且获得大量认可,甚至某大厂员工已经选用作为内部博客,因此我决定写这篇文章向更多人安利它 ...
- 工程师泄露5G核心技术文档 被判有期徒刑三年缓刑四年
2002 年至 2017 年 1 月,黄某瑜就职于中兴通讯公司,担任过射频工程师.无线架构师等职务.2008 年 4 月至 2016 年 10 月,王某就职于中兴通讯公司西安研究所,担任过 RRU 部 ...
- from _sqlite3 import * ImportError: DLL load failed: 找不到指定的模块。
*Error creating Django application: Error on python side. Exit code: 1, err: Traceback (most recent ...
- Vue 2.x折腾记 - (17) 基于Ant Design Vue 封装一个配置式的表单组件
前言 写了个类似上篇搜索的封装,但是要考虑的东西更多. 具体业务比展示的代码要复杂,篇幅太长就不引入了. 效果图 2019-04-25 添加了下拉多选的渲染,并搜索默认过滤文本而非值 简化了渲染的子组 ...
- R 语言命令行参数处理
在unix.windows外部需要调用R脚本执行,然后又需要输入不同的参数,类似shell脚本的命令行参数输入,可以使用Rcript命令实现. 命令格式:Rscript [options] [-e e ...
- HDU 1421 搬寝室 解题报告(超详细)
**搬寝室 Time Limit: 2000/1000 MS Memory Limit: 65536/32768 K Problem Description 搬寝室是很累的,xhd深有体会.时间追述2 ...
- 疯子的算法总结(六) 复杂排序算法 ① 归并排序 merge_sort()
归并排序采取了分治的思想,每次分别排左半边和右半边,不断递归调用自己,直到只有一个元素递归结束,开始回溯,调用merge函数,合并两个有序序列,再合并的时候每次给末尾追上一个最大int这样就不怕最后一 ...
- 图论-欧拉图-欧拉回路-Euler-Fluery-Hierholzer-逐步插入回路法-DFS详解-并查集
欧拉图性质: 1.无向连通图G是欧拉图,当且仅当G不含奇数度结点(G的所有结点度数为偶数): 2.无向连通图G含有欧拉通路,当且仅当G有零个或两个奇数度的结点: 3.有向连通图D是欧拉图,当且仅当该图 ...