系列文章
- 基于 abp vNext 和 .NET Core 開發博客專案 - 使用 abp cli 搭建專案
- 基于 abp vNext 和 .NET Core 開發博客專案 - 給專案瘦身,讓它跑起來
- 基于 abp vNext 和 .NET Core 開發博客專案 - 完善與美化,Swagger登場
- 基于 abp vNext 和 .NET Core 開發博客專案 - 資料訪問和代碼優先
- 基于 abp vNext 和 .NET Core 開發博客專案 - 自定義倉儲之增刪改查
- 基于 abp vNext 和 .NET Core 開發博客專案 - 統一規范API,包裝回傳模型
- 基于 abp vNext 和 .NET Core 開發博客專案 - 再說Swagger,分組、描述、小綠鎖
- 基于 abp vNext 和 .NET Core 開發博客專案 - 接入GitHub,用JWT保護你的API
- 基于 abp vNext 和 .NET Core 開發博客專案 - 例外處理和日志記錄
- 基于 abp vNext 和 .NET Core 開發博客專案 - 使用Redis快取資料
- 基于 abp vNext 和 .NET Core 開發博客專案 - 集成Hangfire實作定時任務處理
- 基于 abp vNext 和 .NET Core 開發博客專案 - 用AutoMapper搞定物件映射
- 基于 abp vNext 和 .NET Core 開發博客專案 - 定時任務最佳實戰(一)
- 基于 abp vNext 和 .NET Core 開發博客專案 - 定時任務最佳實戰(二)
- 基于 abp vNext 和 .NET Core 開發博客專案 - 定時任務最佳實戰(三)
- 基于 abp vNext 和 .NET Core 開發博客專案 - 博客介面實戰篇(一)
- 基于 abp vNext 和 .NET Core 開發博客專案 - 博客介面實戰篇(二)
- 基于 abp vNext 和 .NET Core 開發博客專案 - 博客介面實戰篇(三)
- 基于 abp vNext 和 .NET Core 開發博客專案 - 博客介面實戰篇(四)
- 基于 abp vNext 和 .NET Core 開發博客專案 - 博客介面實戰篇(五)
- 基于 abp vNext 和 .NET Core 開發博客專案 - Blazor 實戰系列(一)
- 基于 abp vNext 和 .NET Core 開發博客專案 - Blazor 實戰系列(二)
- 基于 abp vNext 和 .NET Core 開發博客專案 - Blazor 實戰系列(三)
- 基于 abp vNext 和 .NET Core 開發博客專案 - Blazor 實戰系列(四)
- 基于 abp vNext 和 .NET Core 開發博客專案 - Blazor 實戰系列(五)
- 基于 abp vNext 和 .NET Core 開發博客專案 - Blazor 實戰系列(六)
- 基于 abp vNext 和 .NET Core 開發博客專案 - Blazor 實戰系列(七)
- 基于 abp vNext 和 .NET Core 開發博客專案 - Blazor 實戰系列(八)
- 基于 abp vNext 和 .NET Core 開發博客專案 - Blazor 實戰系列(九)
- 基于 abp vNext 和 .NET Core 開發博客專案 - 終結篇之發布專案
在開始本篇正文之前,解決一個 @瘋瘋過 指出的錯誤,再次感謝指正,

步驟如下:
- 刪掉
.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 = "??介面檔案 - 阿星Plus???";
});
}
...
options.DefaultModelsExpandDepth(-1);是模型的默認擴展深度,設定為 -1 完全隱藏模型,
options.DocExpansion(DocExpansion.List);代表API檔案僅展開標記,不默然展開所有介面,需要我們手動去點擊才展開,可以自行查看DocExpansion,
options.RoutePrefix = string.Empty;代表路由設定為空,直接打開頁面就可以訪問了,
options.DocumentTitle = "??介面檔案 - 阿星Plus???";是設定檔案頁面的標題的,
完成以上操作,在Controller中使用 Attribute:[ApiExplorerSettings(GroupName = ...)]指定是哪個分組然后就可以愉快的使用了,
默認不指定的話就是全部都有,目前只有兩個Controller,我們將HelloWorldController設定成v3,BlogController設定成v1,
//HelloWorldController.cs
...
[ApiExplorerSettings(GroupName = Grouping.GroupName_v3)]
public class HelloWorldController : AbpController
{
...
}
...
//BlogController.cs
...
[ApiExplorerSettings(GroupName = Grouping.GroupName_v1)]
public class BlogController : AbpController
{
...
}
...
編譯運行,打開我們的Swagger檔案看一下,


自己試著換切換一下分組試試吧,大功告成,?
描述
在Swagger檔案中,默認只顯示我們的Controller的名稱,其實他也是支持描述資訊的,這是就需要我們自行擴展了,在.Swagger層新建一個檔案夾Filters,添加SwaggerDocumentFilter類來實作IDocumentFilter介面,
//SwaggerDocumentFilter.cs
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Collections.Generic;
using System.Linq;
namespace Meowv.Blog.Swagger.Filters
{
/// <summary>
/// 對應Controller的API檔案描述資訊
/// </summary>
public class SwaggerDocumentFilter : IDocumentFilter
{
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
{
var tags = new List<OpenApiTag>
{
new OpenApiTag {
Name = "Blog",
Description = "個人博客相關介面",
ExternalDocs = new OpenApiExternalDocs { Description = "包含:文章/標簽/分類/友鏈" }
}
new OpenApiTag {
Name = "HelloWorld",
Description = "通用公共介面",
ExternalDocs = new OpenApiExternalDocs { Description = "這里是一些通用的公共介面" }
}
};
// 按照Name升序排序
swaggerDoc.Tags = tags.OrderBy(x => x.Name).ToList();
}
}
}
實作Apply(...)方法后,使用Linq語法對檔案排個序,然后最重要的使用這個Filter,在擴展方法AddSwagger(...)中使用
public static IServiceCollection AddSwagger(this IServiceCollection services)
{
return services.AddSwaggerGen(options =>
{
...
// 應用Controller的API檔案描述資訊
options.DocumentFilter<SwaggerDocumentFilter>();
});
}
再打開Swagger檔案看看效果,

ok,此時描述資訊也出來了,
小綠鎖
在Swagger檔案中開啟小綠鎖是非常簡單的,只需添加一個包:Swashbuckle.AspNetCore.Filters,直接使用命令安裝:Install-Package Swashbuckle.AspNetCore.Filters
然后再擴展方法AddSwagger(this IServiceCollection services)中呼叫
public static IServiceCollection AddSwagger(this IServiceCollection services)
{
return services.AddSwaggerGen(options =>
{
...
var security = new OpenApiSecurityScheme
{
Description = "JWT模式授權,請輸入 Bearer {Token} 進行身份驗證",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey
};
options.AddSecurityDefinition("oauth2", security);
options.AddSecurityRequirement(new OpenApiSecurityRequirement { { security, new List<string>() } });
options.OperationFilter<AddResponseHeadersFilter>();
options.OperationFilter<AppendAuthorizeToSummaryOperationFilter>();
options.OperationFilter<SecurityRequirementsOperationFilter>();
...
});
}
以上便實作了在Swagger檔案中顯示小綠鎖,我們new的OpenApiSecurityScheme物件,具體引數大家可以自行看一下注釋就明白具體含義,分別呼叫options.AddSecurityDefinition(...)、options.AddSecurityRequiremen(...)、options.OperationFilter(...),編譯運行,打開瞅瞅,

現在只是做了小綠鎖的顯示,但是并沒有實際意義,因為在.net core中還需要配置我們的身份認證授權代碼,才能具體發揮其真正的作用,所以目前我們的api還是處于裸奔狀態,誰都能呼叫你的api,等你發現你寫的文章都被別人刪了,你都不知道為什么,
實作JWT,將在下篇文章中詳細說明,本篇到這里就結束了,我們完善了Swagger檔案,給介面加了分組、描述,還有小綠鎖,老鐵,你學會了嗎???????
開源地址:https://github.com/Meowv/Blog/tree/blog_tutorial
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/27079.html
標籤:.NET Core
上一篇:dotnet OpenXml SDK 形狀填充漸變色的主題色
下一篇:[Asp.Net Core] Blazor Server Side 擴展用途 - 配合CEF來制作帶瀏覽器核心的客戶端軟體 (二) 可運行版本
