在開始本篇正文之前,解決一個 @瘋瘋過 指出的錯誤,再次感謝指正。 步驟如下: 刪掉 層中的項目引用,添加nuget依賴包 ,可以使用命令: 在 層中引用項目 ,在模塊類中添加依賴 將 層中的引用項目 改成 。 上一篇文章(https://www.cnblogs.com/meowv/p/129244 ...
在開始本篇正文之前,解決一個 @瘋瘋過 指出的錯誤,再次感謝指正。
步驟如下:
- 刪掉
.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 = "