Asp.net core中間件實現原理及用法解說


Asp.net core中間件實現原理及用法解說

 

簡述asp.net core中間件的實現思路

 

一次http請求的過程,就是對一個Request請求進行若干次邏輯處理,並最終設置Response的過程。從代碼的實現維度看,由於RequestResponse都在HttpContext里,可將此過程表示為“以一個httpContext為輸入的委托函數”,即delegate Task RequestDelegate(HttpContext context),為方便此文的描述,我們將此委托函數暫時稱為“請求處理邏輯”

 

 

而中間件的作用,就是在請求的后面加入一個處理邏輯,這個處理邏輯是以“前一個請求處理邏輯”為輸入,並經過中間件自己的處理后,返回一個“新的請求處理邏輯”。所以從代碼上可將“中間件”表式為以一個“請求處理邏輯”為輸入並返回另一個“請求處理邏輯”的委托,即Func<RequestDelegate,RequestDelegate>。而多個中間件即表示為List<Func<RequestDelegate,RequestDelegate>>

 

 

Asp.net core中間件的核心功能就是如何將一系列的中間件,合並成一個“請求處理邏輯”的過程,即如何將List<Func<RequestDelegate,RequestDelegate>>合並生成一個RequestDelegate。合並邏輯如下

 

 

上面的代碼有兩個地方要注意

1、asp.net core會默認在請求的最后加入一個“404”處理的中間件。   

2、合並時,組件是先反序后再循環的

   因先加入的中間件要先執行,所以在合並時,第一個中間件要最后合並,即要倒序后再循環合並中間件

 

如何使用中間件

使用中間件有四種方法:UseRunMap和使用Middleware class,但前三種方法最終調用的都是Use方法,我們來看看Use方法的實現邏輯,如下

 

 

use方法只是在中間件列表(_components)的最后再加入一個中間件

 

下面詳細描述四種方法的用法

 

Use的用法

Ues的用法有兩種

用法一

調用IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware),此用法需在middleware委托里自己控制是否要進入下一個中間件,並且要自己創建一個RequestDelegate並返回,寫法會比較復雜。

示例如下

 

用法二

調用IApplicationBuilder Use(this IApplicationBuilder app, Func<HttpContext, Func<Task>, Task> middleware),這是一個擴展方法,此方法不用自己創建RequestDelegate並返回,寫法比較簡潔。它最終調用的方法還是用法一中的實現,此方法的實現代碼如下。

 

示例如下

 

 

需注意:上面的兩種Use用法,在第二個中間件時,並沒有再調用下一個中間件,這是為了確保http請求不會進入到asp.net core默認的最后一個404中間件,因為最后一個404中間件設置了status code,而一但response body之前已經開始寫入時,是不能再改變status code或是request header的,否則會報錯。微軟的官方文檔里要求中間件的使用要遵循如下規則:如response body改變后就不要再調用下一個中間件,避免下一個中間件對上一個中間件的httpcontext內容的污染。(本文示例為演示目的,未遵循此約定)

 

 

 

run的用法

run方法的實現代碼如下

 

注意:從run方法的實現的代碼可以看出,run是不會再執行下一個中間件的,所以第一個中間run方法后面的中間件都不會起作用。所以一般用run時都是放在中間件的最后

 

 

map的用法

map其實准確來說不是中間件的用法,而是新開一個“中間件請求路線分支”,在這個“分支”里,可以再用userun方法來組件一個新的中間件邏輯。

示例如下

 

如上示例,請求地址當能匹配上/test里,才會啟用map里的中間件

 

Middleware class的用法

Middleware class不需要繼承任何類或是接口,但必須有名為Invoke,返回類型為Task,且第一個參數為HttpContext類型的方法。

示例如下

 

 

 

 

Asp.net core內置中間件的介紹

 

中間件名稱

如何使用及說明

Authentication

App.UseAuthentication,驗證當前請求的用戶,並設置HttpContext.User,當OAuth callbacks時,會中止執行下一個中間件。放到要用到用戶驗證的中間件前面

Static File

app.UseStaticFiles(),判斷當前請求是否為靜態文件,如果是則中止執行下一個中間件,否則繼續下一個中間件。放到管道的最前

Response Caching

app.UseResponseCaching(),緩存中間件

MVC

app.UseMvc(),將MVC引入到中間件管道,如果請求的地址能找到對應的MVC路由,則中止執行下一個中間件。放到管道的最后。

Exception

app.UseDeveloperExceptionPage();或app.UseExceptionHandler();用於處理程序的異常信息。放到管道的最前

Authorization 

授權中間件。不需直接引用,App.UseMvc()會在內部調用,並配合app.UseAuthentication()一起使用。

 

 

中間件的總結

1、通過use,run,map,middleware class四種方法使用

2、使用多個中間件時,需注意中間件的順序

3、在設計中間件時,請遵循“責任分離”原則,即一個中間件只對“單一責任”進行處理,如驗證用戶、授權等。

4、如果對response body做了修改后,請不要再執行下一個中間件

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM