以目前流行的前後端分離模式來看,ABP框架更適用於後端開發,而對API接口的管理就成了一項必不可少的功能。
1.安裝Swashbuckle.AspNetCore
使用Nuget管理器在分佈式服務層和展現層AbpDemo.Web安裝Swashbuckle.AspNetCore程序包,包含Swashbuckle.AspNetCore.Swagger、Swashbuckle.AspNetCore.SwaggerGen、Swashbuckle.AspNetCore.SwaggerUI三項。
2.配置Swagger選項
對於Swagger的配置主要是在AbpDemo.Web項目中的Startup啓動類。
在ConfigureServices方法中添加配置:
services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1",
new OpenApiInfo {
Title = "AbpDemo",
Version = "v1.0",
Description="",
TermsOfService=new Uri("https://github.com/ludewig"),
Contact = new OpenApiContact { Name="ludewig",Email="[email protected]",Url=new Uri("https://github.com/ludewig") }
});
options.DocInclusionPredicate((docName, description) => true);
});
在Configure方法中添加配置:
app.UseSwagger();
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/v1/swagger.json", "Demo API v1");
});
此時啓動項目,輸入默認地址http://xxx:xx/swagger/index.html就可以訪問swagger的API接口管理界面。
3.添加註釋信息
但是現在界面包含的信息還比較少,在代碼中的註釋還沒加進來。
打開應用層AbpDemo.Application的屬性界面,選擇“生成”選項,勾選“XML文檔文件”,這樣再次編譯項目時,代碼註釋會以XML文件形式生成到AbpDemo.Web項目中。
同時還要在AbpDemo.Web項目中修改Startup啓動類以便於Swagger能夠讀取到生成的XML文件。
services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1",
new OpenApiInfo {
Title = "AbpDemo",
Version = "v1.0",
Description="",
TermsOfService=new Uri("https://github.com/ludewig"),
Contact = new OpenApiContact { Name="ludewig",Email="[email protected]",Url=new Uri("https://github.com/ludewig") }
});
options.DocInclusionPredicate((docName, description) => true);
var filePath = Path.Combine(AppContext.BaseDirectory, "AbpDemo.Application.xml");
options.IncludeXmlComments(filePath);
});
4.使用API接口管理界面
經過上面的配置步驟後再次啓動項目,可以查看到swagger的界面了。
通過swagger的API管理界面,可以對API接口的輸入輸出數據結構進行查看和測試。
5.ABP框架中Swagger的其他配置
5.1關於CSRF
按照前面的步驟完成對Swagger的配置後,啓動項目,測試接口卻發現報錯了。這其實是ABP框架本身的機制導致的。ABP框架默認是開啓CSRF保護的,也就是啓動了對Cross-Site Request Forgery (CSRF) 跨站請求僞造的防護機制,客戶端必須攜帶可信的token令牌才能訪問API接口。解決這個問題有兩種方式:
- 關閉CSRF保護
在Startup啓動類的ConfigureServices方法中註釋如下代碼
services.AddControllersWithViews(options =>
{
//註釋下列代碼關閉CSRF保護
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
})
- 添加CSRF token
添加用於寫入token信息的腳本文件,設置文件屬性爲“嵌入的資源”並注入到項目中。在Startup啓動類中注入腳本文件。
app.UseSwaggerUI(options =>
{
//...
options.InjectJavascript("ui/abp.js");//注入腳本文件
});
腳本文件內容如下:
var getCookieValue = function(key) {
var equalities = document.cookie.split('; ');
for (var i = 0; i < equalities.length; i++) {
if (!equalities[i]) {
continue;
}
var splitted = equalities[i].split('=');
if (splitted.length !== 2) {
continue;
}
if (decodeURIComponent(splitted[0]) === key) {
return decodeURIComponent(splitted[1] || '');
}
}
return null;
};
var csrfCookie = getCookieValue("XSRF-TOKEN");
var csrfCookieAuth = new SwaggerClient.ApiKeyAuthorization("X-XSRF-TOKEN", csrfCookie, "header");
swaggerUi.api.clientAuthorizations.add("X-XSRF-TOKEN", csrfCookieAuth);
5.2添加自定義首頁
路徑http://xxxx:xx/swagger/index.html對應的首頁是系統默認的API管理界面,內嵌在Swashbuckle.AspNetCore程序包中,頁面包含內容如下:
<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>%(DocumentTitle)</title>
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" >
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
<style>
html
{
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after
{
box-sizing: inherit;
}
body
{
margin:0;
background: #fafafa;
}
</style>
%(HeadContent)
</head>
<body>
<div id="swagger-ui"></div>
<!-- Workaround for https://github.com/swagger-api/swagger-editor/issues/1371 -->
<script>
if (window.navigator.userAgent.indexOf("Edge") > -1) {
console.log("Removing native Edge fetch in favor of swagger-ui's polyfill")
window.fetch = undefined;
}
</script>
<script src="./swagger-ui-bundle.js"> </script>
<script src="./swagger-ui-standalone-preset.js"> </script>
<script>
window.onload = function() {
var configObject = JSON.parse('%(ConfigObject)');
var oauthConfigObject = JSON.parse('%(OAuthConfigObject)');
// If validatorUrl is not explicitly provided, disable the feature by setting to null
if (!configObject.hasOwnProperty("validatorUrl"))
configObject.validatorUrl = null
// If oauth2RedirectUrl isn't specified, use the built-in default
if (!configObject.hasOwnProperty("oauth2RedirectUrl"))
configObject.oauth2RedirectUrl = window.location.href.replace("index.html", "oauth2-redirect.html").split('#')[0];
// Apply mandatory parameters
configObject.dom_id = "#swagger-ui";
configObject.presets = [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset];
configObject.layout = "StandaloneLayout";
// Begin Swagger UI call region
const ui = SwaggerUIBundle(configObject);
ui.initOAuth(oauthConfigObject);
// End Swagger UI call region
window.ui = ui
}
</script>
</body>
</html>
可以看到默認的首頁已經提供了配置對象ConfigObject、驗證授權配置對象OAuthConfigObject、驗證地址ValidatorUrl、驗證授權重定向地址OAuth2RedirectUrl。
如果覺得官方提供的首頁在樣式或功能上不滿足要求,可以創建自定義的首頁添加到wwwroot目錄下,並設置文件屬性爲“嵌入的資源”。然後在Startup啓動類的Configure方法中設置自定義的首頁。
app.UseSwaggerUI(options =>
{
//...
options.IndexStream = () => Assembly.GetExecutingAssembly().GetManifestResourceStream("AbpDemo.Web.wwwroot.swagger.ui.index.html");
//...
});
更多詳細功能可以參考swagger官方文檔