基于 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 开发博客项目 - 给项目瘦身,让它跑起来 ...
随机推荐
- Vue学习—— Vuex学习笔记
组件是Vue最强大的功能之一,而组件实例的作用域是相互独立的,意味着不同组件之间的数据是无法相互使用.组件间如何传递数据就显得至关重要,这篇文章主要是介绍Vuex.尽量以通俗易懂的实例讲述这其中的差别 ...
- C# 多线程(18):一篇文章就理解async和await
目录 前言 async await 从以往知识推导 创建异步任务 创建异步任务并返回Task 异步改同步 说说 await Task 说说 async Task 同步异步? Task封装异步任务 关于 ...
- pycharm(py 文件中添加作者、时间)
1.打开 Pycharm,点击 File,再找到 Settings... 2.选择 Editor ----> File and Code Templates ----> Python Sc ...
- Python编程求解第1天1分钱之后每天两倍持续一个月的等比数列问题
一.问题 问题1 场景:如果你未来的丈母娘要求你,第1天给她1分钱,第2天给2分钱,第3天给4分钱,以此类推,每天给前一天的2倍,给1个月(按30天)算就行.问:第30天给多少钱,总共给多少钱? 问题 ...
- 手把手教你使用ADB卸载手机内置App软件
[一.前言] 不知道你们有没有那么一段黑暗时期,刚买个手机,手机上内置一堆app,还卸载不掉,然后每天各种广告,手机一共1G的运行内存,那些流氓app还要再占走一些内存,真是让人欲哭无泪啊,后来我就学 ...
- 工厂模式(factory pattern)
工厂模式主要用来封装对象的创建,有3种分类:简单工厂(simple factory).工厂方法(factory method).抽象工厂(abstract factory). 简单工厂包括3种组成元素 ...
- P1680 奇怪的分组(组合数+逆元)
传送门戳我 首先将n减去所有的Ci,于是是原问题转换为:n个相同的球放入m个不同盒子里,不能为空,求方案数. 根据插空法:n个球,放到m个箱子里去不能为空,也就是有m-1块板子放在n-1个空隙之间 那 ...
- P2002 消息扩散(缩点)
描述:https://www.luogu.com.cn/problem/P2002 有n个城市,中间有单向道路连接,消息会沿着道路扩散,现在给出n个城市及其之间的道路,问至少需要在几个城市发布消息才能 ...
- Java创建对象的六种方法-权当记录一下
1 简介 Java是面向对象的编程语言,只要使用它,就需要创建对象.Java创建对象有六种方法,实际常用的不会这么多,这里权当是记录一下. 2 六种方法 (1)使用new关键字 Pumpkin p1 ...
- Spring源码阅读 之 配置的读取,解析
在上文中我们已经知道了Spring如何从我们给定的位置加载到配置文件,并将文件包装成一个Resource对象.这篇文章我们将要探讨的就是,如何从这个Resouce对象中加载到我们的容器?加载到容器后又 ...