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>>app

 

 

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

 

 

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

一、asp.net core會默認在請求的最後加入一個「404」處理的中間件。   ui

二、合併時,組件是先反序後再循環的this

   因先加入的中間件要先執行,因此在合併時,第一個中間件要最後合併,即要倒序後再循環合併中間件spa

 

如何使用中間件

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

 

 

use方法只是在中間件列表(_components)的最後再加入一箇中間件設計

 

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

 

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()一塊兒使用。

 

 

中間件的總結

一、經過use,run,map,middleware class四種方法使用

二、使用多箇中間件時,需注意中間件的順序

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

4、若是對response body作了修改後,請不要再執行下一個中間件

相關文章
相關標籤/搜索