.NET Core技術研究-中介軟體的由來和使用
我們將原有ASP.NET應用升級到ASP.NET Core的過程中,會遇到一個新的概念:中介軟體。
中介軟體是ASP.NET Core全新引入的概念。中介軟體是一種裝配到應用管道中以處理請求和響應的軟體。 每個元件:
- 選擇是否將請求傳遞到管道中的下一個元件。
- 可在管道中的下一個元件前後執行工作。
單獨看以上中介軟體的定義,一個很直觀的感覺:中介軟體是HTTP請求管道中的一層層的AOP擴充套件。
在展開介紹中介軟體之前,我們先回顧一下ASP.NET中HttpHandler和HttpModule的處理方式。
一、ASP.NET中HttpHandler和HttpModule
先看一張圖:
上圖中有兩個概念HttpHandler和HttpModule,其中:
HttpHandler用於處理具有給定檔名或副檔名的請求。比如上圖中的.report類的請求,同時,任何一個HttpHandler都需要實現介面IHttpHandler,都需要在Web.Config配置檔案中註冊使用。
HttpModule用於處理每個請求呼叫,比如上圖中的Authorization Module,每個Http請求都會經過HttpModule的處理。通過HttpModule可以中斷Http請求,可以自定義HttpResponse返回。同時,任何一個HttpModule都需要實現介面IHttpModule,都需要在Web.Config配置檔案中註冊使用。
ASP.NET Core引入了中介軟體來實現上面2種Http請求處理擴充套件。ASP.NET Core中介軟體和 ASP.NET HttpHandler HttpModule有什麼區別?
二、ASP.NET Core中介軟體和 ASP.NET HttpHandler HttpModule的區別
1. 中介軟體比HttpHandler、HttpModule更簡單
-
"模組"、"處理程式"、" Global.asax.cs"、 "WEB.CONFIG" (IIS配置除外)和 "應用程式生命週期" 消失
-
中介軟體已使用HttpHandler HttpModule的角色
-
中介軟體使用程式碼而不是在 web.config 中進行配置
-
通過管道分支,可以將請求傳送到特定的中介軟體,不僅可以基於 URL,還可以傳送到請求標頭、查詢字串等。
2. 中介軟體類似於HttpModule
-
處理每個請求呼叫
-
可以實現Http請求中間和繼續
-
能夠建立自定義的HttpResponse
3. 中介軟體和HttpModule按不同的順序處理
-
中介軟體的順序取決於它們插入請求管道的順序,而模組的順序主要基於應用程式生命週期事件
-
中介軟體中Http響應的順序與Http請求的順序相反,而對於HttpModule,請求和響應的順序是相同的。
三、ASP.NET Core中介軟體的設計原理
ASP.NET Core 請求管道包含一系列請求委託,依次呼叫。 下圖演示了這一概念。 沿黑色箭頭執行。
每個請求委託(中介軟體)都可以在下一個請求委託(中介軟體)之前和之後執行操作。中介軟體中的異常處理委託應該在管道的早期被處理,這樣就可以捕獲在管道後期發生的異常。
在Startup.Configure 方法中新增中介軟體元件的順序定義了針對請求呼叫這些中介軟體的順序,以及響應的相反順序。 這個順序對於安全性、效能和功能非常重要。
看一段示例程式碼:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseDatabaseErrorPage(); } else { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); // app.UseCookiePolicy(); app.UseRouting(); // app.UseRequestLocalization(); // app.UseCors(); app.UseAuthentication(); app.UseAuthorization(); // app.UseSession(); app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); }
上述程式碼中每個中介軟體擴充套件方法都通過 Microsoft.AspNetCore.Builder 名稱空間在 IApplicationBuilder 上公開。
app.Use***都是各種常用的內建中介軟體。比如:
1. 異常處理類中介軟體。如上述程式碼中:
當應用在開發環境中執行時:異常顯示頁中介軟體 (UseDeveloperExceptionPage) 報告應用執行時錯誤。資料庫錯誤頁中介軟體報告資料庫執行時錯誤。(app.UseDatabaseErrorPage();)
當應用在生產環境中執行時:異常處理程式中介軟體 (UseExceptionHandler) 捕獲以下中介軟體中引發的異常。TTP 嚴格傳輸安全協議 (HSTS) 中介軟體 (UseHsts) 新增 Strict-Transport-Security 標頭。
2. HTTPS 重定向中介軟體 (UseHttpsRedirection) 將 HTTP 請求重定向到 HTTPS。
3. 靜態檔案中介軟體 (UseStaticFiles) 返回靜態檔案,並簡化進一步請求處理。
4. Cookie 策略中介軟體 (UseCookiePolicy) 使應用符合歐盟一般資料保護條例 (GDPR) 規定。
5. 用於路由請求的路由中介軟體 (UseRouting)。
6. 身份驗證中介軟體 (UseAuthentication) 嘗試對使用者進行身份驗證,然後才會允許使用者訪問安全資源。
7. 用於授權使用者訪問安全資源的授權中介軟體 (UseAuthorization)。
8. 會話中介軟體 (UseSession) 建立和維護會話狀態。 如果應用使用會話狀態,請在 Cookie 策略中介軟體之後和 MVC 中介軟體之前呼叫會話中介軟體。
9. 用於將 Razor Pages 終結點新增到請求管道的終結點路由中介軟體(帶有 MapRazorPages 的 UseEndpoints)。
10. 對於單頁應用程式 (SPA),SPA 中介軟體 UseSpaStaticFiles 通常是中介軟體管道中的最後一個。 SPA 中介軟體處於最後的作用是:允許所有其他中介軟體首先響應匹配的請求。允許具有客戶端側路由的 SPA 針對伺服器應用無法識別的所有路由執行。
還有很多其他的內建中介軟體,可以參考連結:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-3.0。如下圖,
瞭解了ASP.NET Core內建的中介軟體之後,我們可能需要自定義一些中介軟體,比如說原有的ASP.NET HttpModule和HttpHandler.
接下來第四部分,我們繼續示例:
四、自定義中介軟體
將已有HttpModule用自定義中介軟體實現
先看一下原有HttpModule的一個實現:
/// <summary> /// 自定義HTTP擴充套件模組 /// </summary> public class CustomerHttpModule : IHttpModule { public void Init(HttpApplication context) { context.BeginRequest += Context_BeginRequest; } private void Context_BeginRequest(object sender, EventArgs e) { HttpApplication app = (HttpApplication)sender; // Do something } public void Dispose() { } }
遷移到中介軟體實現:
/// <summary> /// 自定義中介軟體 /// </summary> public class CustomerMiddleware { private readonly RequestDelegate _next; public CustomerMiddleware(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext context) { // Do something with context near the beginning of request processing. await _next.Invoke(context); // Clean up. } }
同時增加IApplicationBuilder的一個擴充套件方法:
public static IApplicationBuilder UseCustomerMiddleware(this IApplicationBuilder builder) { return builder.UseMiddleware<CustomerMiddleware>(); }
Startup中使用這個中介軟體:
app.UseCustomerMiddlewares();
以上是對ASP.NET Core中中介軟體的技術由來整理和使用分享。
周國慶
2020/4/4
&n