【從零開始搭建本身的.NET Core Api框架】(一)建立項目並集成swagger:1.2 swagger的高級應用

系列目錄html

.  建立項目並集成swagger
node

  1.1 建立json

  1.2 完善api

二. 搭建項目總體架構安全

三. 集成輕量級ORM框架——SqlSugar服務器

  3.1 搭建環境架構

  3.2 實戰篇:利用SqlSugar快速實現CRUDapp

  3.3 生成實體類框架

四. 集成JWT受權驗證ide

 


 

 

前一章咱們在項目中初步集成了swagger插件,可是還有一些問題須要解決,因此這一章要作的,就是完善swagger的相關設置。

 

  1. 設置swagger ui頁面爲啓動頁

在前一章的末尾,咱們經過在域名後面輸入/swagger後,成功訪問到swagger ui頁,可是咱們發現每次運行項目,都會默認訪問api/values這個接口,我想要將啓動頁設爲swagger(或者是你畫好的任一個html頁),那應該怎麼設置呢?

位置就在Properties下的launchSettings.json文件裏,只要將profiles下的launchUrl改爲你須要的地址就能夠

 

固然,文件裏還有其餘一些基本設置,好比端口設置,就不一一說了。

 

  2. 註釋問題

swagger很重要的一個功能,就是將咱們接口的註釋信息和參數(包括實體類)的註釋信息顯示到頁面上。

如今咱們分別將控制器、函數和參數添加相應的註釋(添加方式是在類或函數的上一行敲三下「/」)

 

F5運行,發現swagger ui上並無將它們顯示出來。那是由於還缺乏兩步

 2.1項目生成xml註釋文件

右鍵項目名稱=>屬性=>生成

勾選「輸出」下面的「生成xml文檔文件」,後面填寫保存該文檔的地址(xml文件的名字能夠修改,可是不建議修改保存的路徑,而後記住這個地址,待會會用到)

 

操做完以後,咱們會發現錯誤列表會多出不少黃色的警告,提示「缺乏XML註釋」。

這時只須要像以前那樣,在類或函數的上面一行添加註釋便可。(固然,若是沒有強迫症的話,裝做沒看到也是不影響的~)

若是咱們按照剛纔記住的地址去文件夾查看,也能看到對應xml文件。

 2.2啓動類中添加swagger服務來讀取這個xml文件

從新編輯Startup.cs,修改ConfigureServices函數:

     /// <summary> /// This method gets called by the runtime. Use this method to add services to the container. /// </summary> /// <param name="services"></param> public void ConfigureServices(IServiceCollection services) { services.AddMvc(); #region Swagger services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Info { Version = "v1.1.0", Title = "Ray WebAPI", Description = "框架集合", TermsOfService = "None", Contact = new Swashbuckle.AspNetCore.Swagger.Contact { Name = "RayWang", Email = "2271272653@qq.com", Url = "http://www.cnblogs.com/RayWang" } }); //添加讀取註釋服務 var basePath = PlatformServices.Default.Application.ApplicationBasePath; var xmlPath = Path.Combine(basePath, "APIHelp.xml"); c.IncludeXmlComments(xmlPath); }); #endregion }

 

以上兩步完成以後,F5運行調試:

 

咱們以前添加的註釋就所有都出來了。

如今是否是忽然以爲swagger頗有用處了?

 

其實到這兒,細心的人都會發現,有一個地方仍是沒有顯示註釋,就是控制器的名稱(在這個例子裏就是values),咱們以前在代碼裏明明也添加了註釋,這裏卻沒有顯示出來,爲何?

好,接下來要放我我的私藏的大招了~

解決辦法是:在項目中添加一個文件夾「SwaggerHelp」,在該文件加下添加類「SwaggerDocTag」,這個類的做用是根據控制器的名稱向swagger ui額外附加註釋,代碼以下:

using Swashbuckle.AspNetCore.Swagger; using Swashbuckle.AspNetCore.SwaggerGen; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace CKPI.SwaggerHelp { /// <summary> /// Swagger註釋幫助類 /// </summary> public class SwaggerDocTag : IDocumentFilter { /// <summary> /// 添加附加註釋 /// </summary> /// <param name="swaggerDoc"></param> /// <param name="context"></param> public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context) { swaggerDoc.Tags = new List<Tag> { //添加對應的控制器描述 這個是我好不容易在issues裏面翻到的 new Tag { Name = "Values", Description = "測試模塊" }, }; } } }

 

接下來要去Startup.cs添加相應的服務:

using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using CKPI.SwaggerHelp; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Microsoft.Extensions.PlatformAbstractions; using Swashbuckle.AspNetCore.Swagger; namespace RayPI { /// <summary> /// /// </summary> public class Startup { /// <summary> /// /// </summary> /// <param name="configuration"></param> public Startup(IConfiguration configuration) { Configuration = configuration; } /// <summary> /// /// </summary> public IConfiguration Configuration { get; } /// <summary> /// This method gets called by the runtime. Use this method to add services to the container. /// </summary> /// <param name="services"></param> public void ConfigureServices(IServiceCollection services) { services.AddMvc(); #region Swagger services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Info { Version = "v1.1.0", Title = "Ray WebAPI", Description = "框架集合", TermsOfService = "None", Contact = new Swashbuckle.AspNetCore.Swagger.Contact { Name = "RayWang", Email = "2271272653@qq.com", Url = "http://www.cnblogs.com/RayWang" } }); //添加註釋服務 var basePath = PlatformServices.Default.Application.ApplicationBasePath; var xmlPath = Path.Combine(basePath, "APIHelp.xml"); c.IncludeXmlComments(xmlPath); //添加對控制器的標籤(描述) c.DocumentFilter<SwaggerDocTag>(); }); #endregion } /// <summary> /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. /// </summary> /// <param name="app"></param> /// <param name="env"></param> public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseMvc(); #region Swagger app.UseSwagger(); app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "ApiHelp V1"); }); #endregion } } }

 

如今再次運行調試,你會發現,控制器的註釋就能夠顯示了

 

這兒的「測試模塊」的註釋,實際上是從SwaggerDocTag類中讀取出來的,並非控制器自己的註釋。

而後,這只是我我的目前爲止發現的最好好用的方法,若是有人有什麼其餘更好的解決辦法,歡迎你們指教,互相學習~

 

BTW,這裏提一下可能會遇到的問題:若是項目發佈以後,或是上線服務器以後,發現註釋又沒了,十有八九是生成的xml文件路徑的問題。能夠按照以前的步驟,依次排查,從新修改路徑就能夠了。


 

【20180705】更新顯示控制器註釋方法:

經@陸韋裏同窗私信指教,現提供另外一種swagger展現控制器註釋的方法,思路以下:

其實咱們對控制器添加的註釋,已經生成在xml註釋文檔裏了(APIHelp.xml),打開xml文檔,以下:

 

仔細觀察下,其實就能找到它的規律:咱們須要的主要數據都在二級節點<members>裏,三級節點<member>有一個name屬性,這個name的值凡是以「T:」開頭的表示的都是類,凡是以「M:」開頭的表示的都是函數,其中類裏面凡是控制器必然會以「Controller」結尾。

因此咱們要寫一個讀取xml的函數,根據這個規則,將註釋提取出來,就能夠了。

Stratup.cs裏之前地配置不須要改變,只須要從新編輯SwaggerHelp下面的SwaggerDocTag.cs,添加一個GetControllerDesc函數,SwaggerDocTag.cs的完整代碼以下:

using Microsoft.Extensions.PlatformAbstractions; using Swashbuckle.AspNetCore.Swagger; using Swashbuckle.AspNetCore.SwaggerGen; using System.Collections.Generic; using System.IO; using System.Xml; namespace RayPI.SwaggerHelp { /// <summary>
    /// Swagger註釋幫助類 /// </summary>
    public class SwaggerDocTag : IDocumentFilter { /// <summary>
        /// 添加附加註釋 /// </summary>
        /// <param name="swaggerDoc"></param>
        /// <param name="context"></param>
        public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context) { /* swaggerDoc.Tags = new List<Tag> { //添加對應的控制器描述 這個是我好不容易在issues裏面翻到的 new Tag { Name = "Admin", Description = "後臺" }, new Tag { Name = "Client", Description = "客戶端" }, new Tag { Name = "System", Description = "系統" } }; */ swaggerDoc.Tags = GetControllerDesc(); } /// <summary>
        /// 從xml註釋中讀取控制器註釋 /// </summary>
        /// <returns></returns>
        private List<Tag> GetControllerDesc() { List<Tag> tagList = new List<Tag>(); var basePath = PlatformServices.Default.Application.ApplicationBasePath; var xmlpath = Path.Combine(basePath, "APIHelp.xml"); if (!File.Exists(xmlpath))//檢查xml註釋文件是否存在
                return tagList; XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(xmlpath); string memberName = string.Empty;//xml三級節點的name屬性值
            string controllerName = string.Empty;//控制器完整名稱
            string key = string.Empty;//控制器去Controller名稱
            string value = string.Empty;//控制器註釋

            foreach (XmlNode node in xmlDoc.SelectNodes("//member"))//循環三級節點member
 { memberName = node.Attributes["name"].Value; if (memberName.StartsWith("T:"))//T:開頭的表明類
 { string[] arrPath = memberName.Split('.'); controllerName = arrPath[arrPath.Length - 1]; if (controllerName.EndsWith("Controller"))//Controller結尾的表明控制器
 { XmlNode summaryNode = node.SelectSingleNode("summary");//註釋節點
                        key = controllerName.Remove(controllerName.Length - "Controller".Length, "Controller".Length); if (summaryNode != null && !string.IsNullOrEmpty(summaryNode.InnerText) && !tagList.Contains(new Tag { Name = key })) { value = summaryNode.InnerText.Trim(); tagList.Add(new Tag { Name = key, Description = value }); } } } } return tagList; } } }
View Code

點擊F5運行,控制器的註釋就顯示出來了。


 

 【20180705】再次更新顯示控制器註釋方法:

此次應該是終極解決辦法了,並且這個方法其實swagger已經幫咱們集成好了~

其中給swagger添加xml註釋文件的函數叫「IncludeXmlComments」,F12跳轉到定義,摘要是這樣的:

//
        // 摘要: // Inject human-friendly descriptions for Operations, Parameters and Schemas based // on XML Comment files //
        // 參數: // filePath: // An abolsute path to the file that contains XML Comments //
        // includeControllerXmlComments: // Flag to indicate if controller XML comments (i.e. summary) should be used to // assign Tag descriptions. Don't set this flag if you're customizing the default // tag for operations via TagActionsBy.
        public void IncludeXmlComments(string filePath, bool includeControllerXmlComments = false);

能夠看到,函數其實十有兩個參數的,只是第二個參數默認設置了false,而這個參數就是設置是否顯示顯示控制器註釋的。。。

因此只須要更改Startup.cs下ConfigureServices函數中的swagger配置就好了:

c.IncludeXmlComments(apiXmlPath, true);//添加控制器層註釋(true表示顯示控制器註釋)

 


 

 20180703更新:添加headers受權驗證

  3. 爲Swagger添加頭部受權驗證功能

當接口添加了受權驗證以後,咱們是不能直接調用該接口,通常須要在發起的http請求的headers中添加「令牌"進行驗證。用過Postman的應該知道,Postman是能夠手動在headers中添加字段的,下面就要實現swagger添加headers的功能。

這裏以JWT受權驗證爲例,若是須要了解JWT受權驗證的,能夠去該系列的第四篇【從零開始搭建本身的.NET Core Api框架】(四)實戰!帶你半個小時實現JWT受權驗證,有專門介紹。

打開Startup.cs,咱們須要在ConfigService函數中添加以下服務:

services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Info { Version = "v1.1.0", Title = "Ray WebAPI", Description = "框架集合", TermsOfService = "None", Contact = new Swashbuckle.AspNetCore.Swagger.Contact { Name = "RayWang", Email = "2271272653@qq.com", Url = "http://www.cnblogs.com/RayWang" } }); //添加註釋服務 var basePath = PlatformServices.Default.Application.ApplicationBasePath; var xmlPath = Path.Combine(basePath, "APIHelp.xml"); c.IncludeXmlComments(xmlPath); //添加對控制器的標籤(描述) c.DocumentFilter<SwaggerDocTag>(); //手動高亮 //添加header驗證信息 //c.OperationFilter<SwaggerHeader>(); var security = new Dictionary<string, IEnumerable<string>> { { "Bearer", new string[] { } }, }; c.AddSecurityRequirement(security);//添加一個必須的全局安全信息,和AddSecurityDefinition方法指定的方案名稱要一致,這裏是Bearer。 c.AddSecurityDefinition("Bearer", new ApiKeyScheme { Description = "JWT受權(數據將在請求頭中進行傳輸) 參數結構: \"Authorization: Bearer {token}\"", Name = "Authorization",//jwt默認的參數名稱 In = "header",//jwt默認存放Authorization信息的位置(請求頭中) Type = "apiKey" }); });

 

完成以後,F5運行,swagger ui頁面就會多出一個按鈕"Authorize",點擊能夠跳出token填寫頁面,做用能夠去看第四章,這裏就不講了

 


【20180714】更新:設置swagger顯示實體類信息(swagger讀取多個xml註釋文件) 

  4. 顯示實體類註釋

 咱們的WebApi接口大部分都是以實體類做爲對象來傳輸的,可是swagger若是不設置的話是看不到這些實體類的註釋的。

好比,實體類Student以下:

「添加學生」接口,須要接收一個「Student」類:

這裏swagger只是把該實體類的字段一一列出來供測試填寫數據,可是卻看不到註釋。

再好比,「獲取單個學生」接口,調用 後會返回一個學生實體,可是Responses信息中卻只顯示了一個200的狀態碼,而沒有顯示該返回的實體類的信息:

下面,就來解決這個問題:

1)項目生成xml註釋文件

這一步和以前同樣,只是項目要選擇實體類所在項目,而不是控制器層的項目:

 

這裏注意點是,XML文檔文件的路徑最好選擇到控制器層XML註釋文件相同的路徑下,若是生成成功,打開文件夾能夠看到生成的xml文件:

 

2)設置swagger讀取該xml註釋文件

完整的ConfigureServices下swagger配置以下:

services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Info { Version = "v1.1.0", Title = "Ray WebAPI", Description = "框架集合", TermsOfService = "None", Contact = new Swashbuckle.AspNetCore.Swagger.Contact { Name = "RayWang", Email = "2271272653@qq.com", Url = "http://www.cnblogs.com/RayWang" } }); //添加註釋服務
                var basePath = PlatformServices.Default.Application.ApplicationBasePath; var apiXmlPath = Path.Combine(basePath, "APIHelp.xml"); var entityXmlPath = Path.Combine(basePath, "EntityHelp.xml"); c.IncludeXmlComments(apiXmlPath, true);//控制器層註釋(true表示顯示控制器註釋)
 c.IncludeXmlComments(entityXmlPath); //添加控制器註釋 //c.DocumentFilter<SwaggerDocTag>(); //添加header驗證信息 //c.OperationFilter<SwaggerHeader>();
                var security = new Dictionary<string, IEnumerable<string>> { { "Bearer", new string[] { } }, }; c.AddSecurityRequirement(security);//添加一個必須的全局安全信息,和AddSecurityDefinition方法指定的方案名稱要一致,這裏是Bearer。
                c.AddSecurityDefinition("Bearer", new ApiKeyScheme { Description = "JWT受權(數據將在請求頭中進行傳輸) 參數結構: \"Authorization: Bearer {token}\"", Name = "Authorization",//jwt默認的參數名稱
                    In = "header",//jwt默認存放Authorization信息的位置(請求頭中)
                    Type = "apiKey" }); });

 

到這,第一個問題,接受實體類就能夠顯示註釋了:

3)控制器的接口函數頭設置標籤

在接口的頭部添加標籤:

[ProducesResponseType(typeof(Student),200)]

 

代表該接口返回實體類類型。以下圖例:

再次運行項目,查看獲取單個學生接口:

點擊黑框上面「Model」字樣,還能夠查看該類的註釋~

另外,swagger還在接口的下方很貼心的生成了一個用於顯示實體Model模塊:

 

到這,咱們的第一章的內容「搭建項目和集成sawgger」就結束了,若是有問題,歡迎留言一塊兒討論,互相學習。

原本想着代碼比較簡單,就不放源碼,可是考慮以後,仍是決定上傳一下。正好也定個規矩,這個系列後面每完成一個大的章節以後,都上傳一份源碼。這樣也是給本身一個交代吧。

源碼下載:點擊查看下載地址

 

下一章的內容是項目架構的搭建和集成SqlSugar

相關文章
相關標籤/搜索