本文3.0版本文章
https://mp.weixin.qq.com/s/SHNNQoYF-t8i2j85E1oSYA
前言
如果想直接在域名的根目錄直接加載 swagger 比如訪問:localhost:8001 就能訪問,可以這樣設置:
app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "ApiHelp V1"); c.RoutePrefix = "";//路徑配置,設置為空,表示直接訪問該文件,
//路徑配置,設置為空,表示直接在根域名(localhost:8001)訪問該文件,注意localhost:8001/swagger是訪問不到的,
//這個時候去launchSettings.json中把"launchUrl": "swagger/index.html"去掉, 然后直接訪問localhost:8001/index.html即可
});
書接上文《從零開始搭建自己的前后端分離【 .NET Core2.0 Api + Vue 2.0 】框架之三 || Swagger的使用 3.1》,上文中只是簡單的對如何使用Swagger作了介紹,而且最后也提出了幾個問題,這里再重溫下那幾個問題:
為何直接 F5 運行,首頁還是無法加載?
接口雖有,但是卻沒有相應的文字說明?
項目開發中的實體類是如何在Swagger中展示的?
對於接口是如何加權限驗證的?
一、swagger的一般用法
0、設置swagger頁面為首頁——開發環境
在上一回中我們提到,我們直接F5運行項目,出現了系統默認頁,

雖然可以在輸入/swagger后,順利的訪問swagger ui頁,但是我們發現每次運行項目,都會默認訪問api/values這個接口,我想要將啟動頁設為swagger(或者是任意一個頁面),你就需要用到了
**設置文件launchSettings.json **了:


然后你再一次F5 運行,就會發現不一樣了,其他的配置,以及以后部署中的設置,我們會在以后的文章中都有提到。
1、設置默認直接首頁訪問 —— 生產環境
上邊的方法很正常,直接這么運行,就可以了,但是如果我們部署到服務器,就會發現,上邊的那種默認啟動首頁無效了,還是需要我們每次手動在域名后邊輸入 /swagger ,麻煩!
別慌,swagger 給我們提供了這個擴展,我們可以指定一個空字符,作為 swagger 的地址,在Configure中配置中間件:
app.UseSwagger(); app.UseSwaggerUI(c => { c.SwaggerEndpoint($"/swagger/v1/swagger.json", $"Blog.Core v1");// 將swagger設置成首頁 c.RoutePrefix = ""; //路徑配置,設置為空,表示直接在根域名(localhost:8001)訪問該文件,注意localhost:8001/swagger是訪問不到的,去launchSettings.json把launchUrl去掉 });
然后再把我們上邊的項目文件 launchSettings.json 的 launchUrl 給去掉就行了,這樣我們無論是本地開發環境,還是生產環境,都可以默認首頁加載了。
比如我的在線地址 :apk.neters.club/
2、為接口添加注釋
接下來,我們就需要解決第二個問題,如何增加文字說明,就是傳說中的注釋,我們只需要在需要的api接口方法上,連點三次 / 即可:
添加好了注釋,那我們接下來就需要把注釋信息導入到swagger里,需要用到xml文檔,右鍵web 項目名稱=>屬性=>生成,勾選“輸出”下面的“xml文檔文件”,系統會默認生成一個,當然老規矩,你也可以自己起一個名字:
這里我用的是相對路徑,可以直接生成到 api 層的 bin文件夾下:

有了注釋和文檔,那接下來就是導入了,也是很簡單,只需要一行即可:
var basePath = AppContext.BaseDirectory; var xmlPath = Path.Combine(basePath, "Blog.Core.xml");//這個就是剛剛配置的xml文件名 c.IncludeXmlComments(xmlPath);
運行查看,沒問題!
3、忽略注釋警告
這個時候,我們看看有沒有錯誤,一看,咦~~~果然,雖然是警告,可以強迫症呀,一看還挺多

別慌!一看,哦!原來是swagger把一些 action 方法都通過xml文件配置了,如果你不想每一個方法都這么加注釋,可以這么配置(對當前項目進行配置,可以忽略警告,記得在后邊加上分號 ;1591):
這時候你可以看看,所有的警告都已經消失不見了。
4、給控制器也添加注釋
剛剛可能你沒太注意,我們上邊只是給方法加了注釋,但是控制器還沒有加上,那怎么辦呢,有一個復雜的方法,就是添加一個過濾器 c.DocumentFilter<ControllerDescriptionFilter>(); ,然后自己添加一個 .Tags ,但是這個麻煩!不多說,官方已經考慮到了這個問題了,很簡單:
首先我們在控制器上加上注釋:
然后配置swagger的 xml 文檔導入方法:
當當當,出來了:

5、對 Model 也添加注釋說明
接下來開始第三個問題:添加實體類說明注釋
新建一個.net core 類庫Blog.Core.Model,注意是 .net core的類庫,或者使用標准庫也是可以的!(標准庫可以在 NetCore 和 Framework 兩個項目都可以跑)
/// <summary> /// 這是愛 /// </summary> public class Love { /// <summary> /// id /// </summary> public int Id { get; set; } /// <summary> /// 姓名 /// </summary> public string Name { get; set; } /// <summary> /// 年齡 /// </summary> public int Age { get; set; } }

這個時候,我們只需要配置仿照上邊 api 層配置的xml文檔那樣,在 Blog.Core.Model 層的 XML 輸出到 API 層就行了:

2、API 層沒有直接引用 Model 層,而是通過級聯的形式;
就比如我的 Github 上的代碼那樣:
效果和上邊是一樣的,也算是引用 Model 層了。
6、導入model.xml到swagger,然后api添加參數
配置xml文檔
public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); #region Swagger services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Info { Version = "v0.1.0", Title = "Blog.Core API", Description = "框架說明文檔", TermsOfService = "None", Contact = new Swashbuckle.AspNetCore.Swagger.Contact { Name = "Blog.Core", Email = "Blog.Core@xxx.com", Url = "https://www.jianshu.com/u/94102b59cc2a" } }); //就是這里 var basePath = Microsoft.DotNet.PlatformAbstractions.ApplicationEnvironment.ApplicationBasePath;
var basePath2 = AppContext.BaseDirectory;// 這種寫法也是可以的
//就是這里 var xmlPath = Path.Combine(basePath, "Blog.Core.xml");//這個就是剛剛配置的xml文件名 c.IncludeXmlComments(xmlPath, true);//默認的第二個參數是false,這個是controller的注釋,記得修改 var xmlModelPath = Path.Combine(basePath, "Blog.Core.Model.xml");//這個就是Model層的xml文件名 c.IncludeXmlComments(xmlModelPath); }); #endregion }
接口添加注釋
/// <summary> /// post /// </summary> /// <param name="love">model實體類參數</param> [HttpPost] public void Post(Love love) { }
dang dang dang,就出來了

7、去掉Swagger警告提示
在Model層中,我們建立了很多實體,如果你沒有為每一個實體都添加注釋的話,可能會出現這樣的警告:
如果有的小伙伴,不想添加注釋,而又不想看到這個強迫症的警告提示,那就可以這么做,
右鍵項目 屬性 -》 Errors and warnings 配置 1591:
8、隱藏某些接口
如果不想顯示某些接口,直接在controller 上,或者action 上,增加特性
[ApiExplorerSettings(IgnoreApi = true)]
9、自定義 Swagger Index 靜態頁模板
有時候我們為了在頁面上增加一些小東西,比如說一個圖片或者說,修改部分css樣式,甚至更改 js 事件,那我們就必須修改 index.html 頁面,很簡單:
1、首先我們在 api 根目錄下邊創建一個 index.html 頁面,
<!--<script async="async" id="mini-profiler" src="/profiler/includes.min.js?v=4.1.0+c940f0f28d" data-version="4.1.0+c940f0f28d" data-path="/profiler/" data-current-id="" data-ids="" data-position="Left" data-authorized="true" data-max-traces="15" data-toggle-shortcut="Alt+P" data-trivial-milliseconds="2.0" data-ignored-duplicate-execute-types="Open,OpenAsync,Close,CloseAsync"> </script>--> <!--1、版本號要與nuget包一致;2、id不能為空--> <script async="async" id="mini-profiler" src="/profiler/includes.min.js?v=4.1.0+c940f0f28d" data-version="4.1.0+c940f0f28d" data-path="/profiler/" data-current-id="4ec7c742-49d4-4eaf-8281-3c1e0efa8888" data-ids="4ec7c742-49d4-4eaf-8281-3c1e0efa8888" data-position="Left" data-authorized="true" data-max-traces="5" data-toggle-shortcut="Alt+P" data-trivial-milliseconds="2.0" data-ignored-duplicate-execute-types="Open,OpenAsync,Close,CloseAsync"> </script> <!-- HTML for static distribution bundle build --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>%(DocumentTitle)</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700" rel="stylesheet"> <link rel="stylesheet" type="text/css" href="./swagger-ui.css"> <link rel="icon" type="image/png" href="./logo/favicon-32x32.png" sizes="32x32" /> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <style> html { box-sizing: border-box; overflow: -moz-scrollbars-vertical; overflow-y: scroll; } *, *:before, *:after { box-sizing: inherit; } body { margin: 0; background: #fafafa; } .qqgroup { float: right; } .info { float: left; } .download-contents { display: none; } </style> %(HeadContent) </head> <body> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position:absolute;width:0;height:0"> <defs> <symbol viewBox="0 0 20 20" id="unlocked"> <path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V6h2v-.801C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8z"></path> </symbol> <symbol viewBox="0 0 20 20" id="locked"> <path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8zM12 8H8V5.199C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8z" /> </symbol> <symbol viewBox="0 0 20 20" id="close"> <path d="M14.348 14.849c-.469.469-1.229.469-1.697 0L10 11.819l-2.651 3.029c-.469.469-1.229.469-1.697 0-.469-.469-.469-1.229 0-1.697l2.758-3.15-2.759-3.152c-.469-.469-.469-1.228 0-1.697.469-.469 1.228-.469 1.697 0L10 8.183l2.651-3.031c.469-.469 1.228-.469 1.697 0 .469.469.469 1.229 0 1.697l-2.758 3.152 2.758 3.15c.469.469.469 1.229 0 1.698z" /> </symbol> <symbol viewBox="0 0 20 20" id="large-arrow"> <path d="M13.25 10L6.109 2.58c-.268-.27-.268-.707 0-.979.268-.27.701-.27.969 0l7.83 7.908c.268.271.268.709 0 .979l-7.83 7.908c-.268.271-.701.27-.969 0-.268-.269-.268-.707 0-.979L13.25 10z" /> </symbol> <symbol viewBox="0 0 20 20" id="large-arrow-down"> <path d="M17.418 6.109c.272-.268.709-.268.979 0s.271.701 0 .969l-7.908 7.83c-.27.268-.707.268-.979 0l-7.908-7.83c-.27-.268-.27-.701 0-.969.271-.268.709-.268.979 0L10 13.25l7.418-7.141z" /> </symbol> <symbol viewBox="0 0 24 24" id="jump-to"> <path d="M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.41L5.83 13H21V7z" /> </symbol> <symbol viewBox="0 0 24 24" id="expand"> <path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z" /> </symbol> </defs> </svg> <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> var int = null; window.onload = function () { var configObject = JSON.parse('%(ConfigObject)'); var oauthConfigObject = JSON.parse('%(OAuthConfigObject)'); // Apply mandatory parameters configObject.dom_id = "#swagger-ui"; configObject.presets = [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset]; configObject.layout = "StandaloneLayout"; // 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"); // Build a system const ui = SwaggerUIBundle(configObject); // Apply OAuth config ui.initOAuth(oauthConfigObject); int = setInterval(function () { getData(); }, 1000); $("img").attr("src", "./logo/favicon-32x32.png"); } function getData() { console.log(1); if ($(".qqgroup").length <= 0) { $('.info').after("<div class='qqgroup'><img src='http://123.206.33.109:26898/QQGroup.png' alt='QQ二維碼' style='width: 200px;'></div><div style='clear: both;'></div>"); console.log(2); clearInterval(int); } } </script> </body> </html>
我們可以在里邊簡單的修改 css 樣式,或者js 事件,但是注意,如果個人能力不是很高的話,建議不要修改。
2、然后我們修改中間件,替換掉 swagger 的默認首頁
app.UseSwaggerUI(c => { //根據版本名稱倒序 遍歷展示 var ApiName = "Blog.Core";//這里你可以從appsettings.json中獲取,比如我封裝了一個類Appsettings.cs,具體查看我的源代碼 var version = "v1"; c.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"{ApiName} {version}"); // 將swagger首頁,設置成我們自定義的頁面,記得這個字符串的寫法:解決方案名.index.html c.IndexStream = () => GetType().GetTypeInfo().Assembly.GetManifestResourceStream("Blog.Core.index.html");//這里是配合MiniProfiler進行性能監控的,《文章:完美基於AOP的接口性能分析》,如果你不需要,可以暫時先注釋掉,不影響大局。 c.RoutePrefix = ""; //路徑配置,設置為空,表示直接在根域名(localhost:8001)訪問該文件,注意localhost:8001/swagger是訪問不到的,去launchSettings.json把launchUrl去掉,如果你想換一個路徑,直接寫名字即可,比如直接寫c.RoutePrefix = "doc"; });
完成,就是這么簡單。
二、結語
對於接口是如何加權限驗證的?
讓我們帶着這些問題,繼續瀏覽下一篇吧,Swagger 3.3 JWT 權限,必看篇。