蘋果力推 M1 Ultra 背後:科技巨頭紛紛押注自主研發晶片
準備翻譯dotnet tutorial網站上一些dotnet方面的知識文章。先從中介軟體開始,原文地址:
ASP.NET Core Middleware with Examples
本文主要討論以下與ASP.NET Core
中介軟體相關概念
- 什麼是
ASP.NET Core
中介軟體 - 在
ASP.NET Core
應用的什麼地方使用中介軟體 - 如何在
ASP.NET Core
應用中配置中介軟體 - 使用中介軟體的例子
-
ASP.NET Core
中介軟體的執行順序 -
ASP.NET Core
中的請求代理是什麼 -
ASP.NET Core
中的Use,Run,Map方法的作用 - 什麼是
UseDeveloperExceptionPage
- 如何使用
Run()
和Use()
擴充套件方法配置中介軟體 - MapGet和Map方法的區別
什麼是ASP.NET Core
中介軟體
ASP.NET Core
中介軟體是一種軟體元件(技術上僅僅是一些C#的類),聚合到應用管線用來處理Http請求和響應。每個中介軟體執行以下任務:
- 選擇是將Http請求傳遞到管線中的下一個中介軟體。通過呼叫中介軟體的next()方法實現。
- 能夠執行一些工作在管線的下一個中介軟體之前和之後。
ASP.NET Core
中有許多內建中介軟體已經可以直接使用。你也可以在你的ASP.NET Core
應用中根據需要建立自己的中介軟體。最重要的是,一個給定的ASP.NET Core
ASP.NET Core
應用中哪裡使用中介軟體
ASP.NET Core
應用中使用中介軟體的一些例子:
- 使用一箇中間件來做使用者認證
- 使用日誌記錄請求和響應
- 使用一箇中間件來處理錯誤(異常)
- 用來處理靜態檔案,如圖片、javascript指令碼或css樣式檔案等
- 使用中介軟體來給使用者授權,指定特定訪問資源
中介軟體通常是我們用來處理 ASP.NET Core
應用請求管線。如果在先前版本的.NET Framework
工作過,你應該知道使用HTTP Handlers 和 HTTP Modules來建立請求處理管線。請求管線將決定HTTP請求和響應將如何執行。
如何在ASP.NET Core
應用中配置中介軟體
在ASP.NET Core
應用中,我們需要在Startup.cs檔案中的Startup類中使用Configure()方法來配置中介軟體(.net5
以上版本沒有該類了)。Startup這個類是在應用開始時執行的。當我們使用空的ASP.NET Core
應用模板建立專案,將會生成如下帶有Configuration()方法的程式碼:
當你需要配置中介軟體時,只需要在startup類中使用Configuration()方法中使用 IApplicationBuilder物件的Use方法。如上圖所示,Configuration()方法僅使用了3箇中間件來建立請求處理管線。這3箇中間件分別是:
-
UseDeveloperExceptionPage()
中介軟體 -
UseRouting()
中介軟體 -
UseEndpoints()
中介軟體
在理解以上三個內建中介軟體之前,先了解什麼是中介軟體以及這些中介軟體如何在ASP.NET Core
應用中工作的。
理解中介軟體
在ASP.NET Core
應用中,中介軟體可以訪問到流入的HTTP請求和流出的HTTP響應,所以可以用來:
- 通過生成一個HTTP響應來處理流入的HTTP請求
- 處理並可以修改流入的HTTP請求,然後將該HTTP請求傳給管線上的下一個中介軟體
- 處理並可以修改流出的HTTP響應,並將HTTP響應傳遞給管線上的下一個中介軟體或
ASP.NET Core
應用(如果管線上已經沒有下一個中介軟體的話)
為了更好理解,下面的圖展示了ASP.NET Core
應用中處理管線如何執行。
如上圖所示,有一個日誌中介軟體。這個中介軟體簡單的記錄下請求時間,然後將請求傳遞給下一個中介軟體-靜態檔案處理中介軟體,用來做後續處理。
ASP.NET Core
應用中的中介軟體也可能通過建立HTTP響應來處理HTTP請求,也可能不呼叫請求管線中的下一個中介軟體。這個概念稱為:請求管線短路。
例如,有一個靜態檔案中介軟體,如果流入HTTP請求是某些靜態檔案,如圖片、CSS樣式檔案、JavaScript指令碼檔案等,靜態檔案中介軟體就可以處理該請求了,它將不再呼叫請求管線中下一個中介軟體:MVC中介軟體,以此來短路請求管線。
ASP.NET Core
應用中的中介軟體不僅能夠訪問HTTP請求,也可以訪問管線中的響應。例如,在本例中的日誌中介軟體可能記錄下響應傳送給客戶端的時間。
ASP.NET Core
中的中介軟體執行順序
理解中介軟體執行順序非常重要。ASP.NET Core
應用中介軟體執行順序是按照他們加入管線的順序。所以,當往請求處理管線中加入中介軟體時需要非常注意順序。
按照你的應用需求,你可能會新增任意數量的中介軟體。例如,如果你開發的僅僅是靜態網站來處理一些靜態的HTML頁面和圖片,那麼你僅需要在請求管線中新增“靜態檔案”中介軟體。
如果你開發的是安全的動態資料驅動web應用,那麼你將需要多箇中間件來完成任務,例如日誌中介軟體,認證中介軟體,授權中介軟體,MVC中介軟體等。
ASP.NET Core
中的請求代理是什麼
在ASP.NET Core
中,請求代理用來建立請求管線,即請求代理是用來處理每個流入HTTP請求的。在 ASP.NET Core
中,你可以使用Run,Map,Use擴充套件方法來配置請求代理。你可以使用一個匿名方法(中介軟體in-line方式)或者建立一個可複用的類來實現請求代理。這些匿名方法或可複用的類即成為中介軟體或中介軟體元件。請求管線中的每個中介軟體都可以觸發或短路下一個中介軟體。
ASP.NET Core
中的Run()
和Use()
擴充套件方法配置中介軟體
在 ASP.NET Core
中,使用Use和Run擴充套件方法來向請求管線中註冊行內中介軟體。Run擴充套件方法允許我們新增終點中介軟體(即該中介軟體後面不會再有中介軟體了)。另一方面,Use擴充套件方法允許我們項請求管線中新增可以繼續呼叫下一個中介軟體的中介軟體。
如果你觀察Configure方法,你會看到它獲取了一個IApplicationBuilder介面的例項,然後使用該例項的擴充套件方法如Use、Run來配置中介軟體元件。
在上面的示例,3箇中間件通過使用IApplicationBuilder的示例註冊到請求管線中。他們分別是:
- UseDeveloperExceptionPage()中介軟體
- UseRouting()
- UseEndpoints() 中介軟體
UseDeveloperExceptionPage
中介軟體
在Configure方法中,UseDeveloperExceptionPage()
中介軟體註冊到請求管線中,該中介軟體僅在伺服器環境被設定為“development”時才會顯示一個圖片。該中介軟體僅當應用中出現一個未處理的異常發生且時在開發模式下,會顯示出現問題的程式碼。你可以考慮使用黃色頁面來代替。稍後下一篇文章將會示例如何使用中介軟體。
UseRouting()
中介軟體
該中介軟體元件用於新增端點路由中介軟體到請求管線,該中介軟體將URL(或者流入HTTP請求)對映到一個特定的資源。將會在後面路由相關的文章討論細節。
UseEndpoints()
中介軟體
在這個中介軟體,使用Map擴充套件方法路由決定。下面是UseEndpoints中介軟體的預設實現。MapGet擴充套件方法,我們將路由設定為"/",說明僅匹配域名。即任何僅包含域名的請求URL均由該中介軟體處理
除了使用MapGet方法,你話可以使用Map方法來對映。
此時執行應用,你將獲得預期的輸出。
MapGet和Map方法的區別
MapGet方法僅處理GET方法的HTTP請求,而Map方法則可以處理GET、POST、PUT以及DELETE的HTTP請求。
如何使用Run擴充套件方法配置中介軟體
接下來我們使用Run擴充套件方法建立並配置自定義的中介軟體。首先,Configure方法中有所有的程式碼註釋。你可以註釋掉所有已有程式碼,然後複製黏貼下面的程式碼到Configure方法中。下面的程式碼向請求管線中註冊了一個簡單的中介軟體,該中介軟體僅列印一些訊息。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.Run(async (context) =>
{
await context.Response.WriteAsync("Getting Response from First Middleware");
});
}
輸出:
我們觸發IApplicationBuilder例項(app變數)Run擴充套件方法,註冊該中介軟體至請求管線。下面是Run方法的定義。
從上面Run方法定義可以看出,該方法實現IApplicationBuilder介面的擴充套件方法。這是為什麼可以使用IApplicationBuilder的例項app呼叫Run擴充套件方法。如果你對擴充套件方法不熟悉,可以先閱讀下面文章。
https://dotnettutorials.net/lesson/extension-methods-csharp/
從上面圖片也能看出,Run方法接收一個輸入引數,型別為RequestDelegate。下面是RequestDelegate的定義。
從上面圖片看出,RequestDelegate代理一類方法,該類方法接收一個型別為HttpContext的引數。如果你對代理不熟悉,可以閱讀下面文章。
https://dotnettutorials.net/lesson/delegates-csharp/
前面一直討論到的ASP.NET Core
中介軟體既能夠訪問HTTP Request,也能訪問HTTP Response,就是因為上面的那個HttpContext物件。
在我們的例子中,我們以行內匿名方法傳遞一個請求代理,並且傳遞HTTPContext物件作為輸入引數給請求代理。如下圖所示:
注意:除了使用行內匿名方法傳遞請求代理外,你也可以定義一個獨立類來傳遞請求代理。後面文章將討論。
再新增一箇中間件
修改Configure方法內的程式碼如下,用來再新增一箇中間件:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.Run(async (context) =>
{
await context.Response.WriteAsync("Getting Response from First Middleware");
});
app.Run(async (context) =>
{
await context.Response.WriteAsync("Getting Response from Second Middleware");
});
}
現在用Run擴充套件方法註冊了2箇中間件。如果你執行應用,將獲得如下輸出
Getting Response from 1st Middleware
僅打印出第一個中介軟體的輸出。原因是我們使用Run擴充套件方法來註冊的中介軟體,使用該方法註冊的中介軟體為端點中介軟體,即他們不會再呼叫請求管線後面的中介軟體了。
使用Use擴充套件方法配置中介軟體
那麼問題來了,如何呼叫請求管線後面的中介軟體呢?答案是使用Use擴充套件方法來註冊中介軟體。如下程式碼所示。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.Use(async (context, next) =>
{
await context.Response.WriteAsync("Getting Response from 1st Middleware");
await next();
});
app.Run(async (context) =>
{
await context.Response.WriteAsync("Getting Response from 2nd Middleware");
});
}
現在執行應用,將會得打預期的輸出,即兩個中介軟體的輸出均顯示出來了。
理解Use擴充套件方法
Use擴充套件方法以行內方式新增一箇中間件代理到請求管線中。下面是Use擴充套件方法的定義:
該方法也是作為IApplicationBuilder介面的一個擴充套件方法來實現。這也是我們能夠使用IApplicationBuilder例項觸發該方法的原因。從該方法定義中可以看出,方法使用兩個輸入引數,第一個引數是HttpContext物件,通過它可以訪問HTTP請求和響應。第二個引數是Func型別,一個泛型代理,可以處理請求或呼叫請求管線中的下一個中介軟體。
注意:如果你想向下一箇中間件傳遞請求,那麼你需要呼叫next方法。
本篇至此結束,下一篇將舉例使用自定義中介軟體。本篇嘗試解釋中介軟體如何在ASP.NET Core
應用中處理請求管線。
譯者新增
這是第一篇嘗試翻譯的文章,儘量理解原作者意思。以後我都會在後面加上譯者,新增一些自己的想法。
由於本篇原作者寫的時候,使用的應該是ASP.NET Core 5
版本以下,所有示例程式碼均在低版本下。5.0以上已經沒有StartUp.cs檔案了,因此實現上略有區別。會在下一篇翻譯完作者舉例使用自定義中介軟體的時候,同時給出高版本的中介軟體實現方式。