Asp.Net Core 中间件应用实战中你不知道的那些事
一、概述
這篇文章主要分享Endpoint?終結點路由的中間件的應用場景及實踐案例,不講述其工作原理,如果需要了解工作原理的同學, 可以點擊查看以下兩篇解讀文章:
?Asp.Net Core EndPoint 終結點路由工作原理解讀?ASP.NET CORE 管道模型及中間件使用解讀
1.1 中間件(Middleware)的作用
我們知道,任何的一個web框架都是把http請求封裝成一個管道,每一次的請求都是經過管道的一系列操作,最終到達我們寫的代碼中。那么中間件就是在應用程序管道中的一個組件,用來攔截請求過程進行一些其他處理和響應。中間件可以有很多個,每一個中間件都可以對管道中的請求進行攔截,它可以決定是否將請求轉移給下一個中間件。
asp.net core 提供了IApplicationBuilder接口來讓把中間件注冊到asp.net的管道請求當中去,中間件是一個典型的AOP應用。下面是一個微軟官方的一個中間件管道請求圖:
1.2 中間件和過濾器的區別
Filter是延續ASP.NET MVC的產物,同樣保留了五種的Filter,分別是Authorization Filter、Resource Filter、Action Filter、Exception Filter及Result Filter。具體可以查看我上次分享的一篇Asp.Net Core Filter 深入淺出的那些事-AOP的文章.
根據描述,可以看出中間件和過濾器的功能類似,那么他們有什么區別?為什么又要搞一個中間件呢?其實,過濾器和中間件他們的關注點是不一樣的,也就是說職責不一樣,干的事情就不一樣。
同作為兩個AOP利器,Filter(過濾器)更貼合業務,它關注于應用程序本身,比如你看ActionFilter?和?ResultFilter,它都直接和你的Action,ActionResult交互了,是不是離你很近的感覺,那我有一些比如對我的輸出結果進行格式化,對我的請求的ViewModel進行數據驗證啦,肯定就是用Filter無疑了。它是MVC的一部分,它可以攔截到你Action上下文的一些信息,而中間件是沒有這個能力的。
可以看到,每一個中間件都都可以在請求之前和之后進行操作。請求處理完成之后傳遞給下一個請求
1.3 中間件的使用場景
那么,何時使用中間件呢?我的理解是在我們的應用程序當中和業務關系不大的一些需要在管道中做的事情可以使用,比如身份驗證,Session存儲,日志記錄等。其實我們的 Asp.net core項目中本身已經包含了很多個中間件。比如 身份認證中間件?UseAuthorization()等系列.
二、中間件實戰
需求場景:通過后端記錄每一次的訪問請求日志,同時需要根據需要排除一些Controller?或者Action?不記錄請求的日志信息。
思考:經過分析我需要創建一個全局的中間件進行攔截路由,并且寫入日志;同時需要添加一個特性Attribute?進行標注那些Controller或者Action?不需要進行日志記錄。
我們來創建LogsMiddleware?中間件代碼,代碼如下:
NoLogsAttriteFilter?過濾器代碼如下:
public class NoLogsAttriteFilter : Attribute {/// <summary>/// 這里加這個主要是把獲取到的信息在中間件中打印出來///,區分中間件的攔截用處/// </summary>public string Message = "";public NoLogsAttriteFilter(string message){Message = message;} }Startup?中的代碼如下:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {app.UseRouting();app.UseAuthorization();app.UseMiddleware<LogsMiddleware>();//添加日志記錄中間件app.UseEndpoints(endpoints?=>{endpoints.MapControllerRoute(name:?"default",pattern:?"{controller=Home}/{action=Index}/{id?}");}); }HomeController?控制器中的兩個Action 代碼如下::
// 訪問該路由會記錄訪問日志 public IActionResult Index() {return?View(); }//訪問該路由不會記錄訪問日志 [NoLogsAttriteFilter("Manage 不需要記錄訪問日志")] public IActionResult Manage() {return?View(); }這樣就自定義日志中間件就已經完成了我上面的需求,不依賴于任何業務獨立存在于系統中;從代碼中我們可以看到中間件通過context.Features.Get<IEndpointFeature>()?.Endpoint;?方法獲得終結點路由方式進行匹配, 自定義中間件教程文章請點擊自定義中間件官方教程[4]?一文。
現在我們再來印證下我上一篇關于?Asp.Net Core EndPoint 終結點路由工作原理解讀?一文 中提及到UseRouting()?中間件是遍歷所有的Endpoint?終結點路由以匹配當前請求的?Endpoint?終結點路由一說,我把注冊LogsMiddleware中間件和UseRouting()?路由中間件代碼順序調整一下,代碼如下:
public void Configure(IApplicationBuilder app,IWebHostEnvironment env) {//?中間件注冊放到了UseRouting()?之前//添加日志記錄中間件app.UseMiddleware<LogsMiddleware>();app.UseRouting();app.UseAuthorization();app.UseEndpoints(endpoints?=>{endpoints.MapControllerRoute(name:?"default",pattern:?"{controller=Home}/{action=Index}/{id?}");}); }再來看看運行調試的結果如圖:
從調試的結果圖中可以看出?endpoint?變量是 null;所有需要使用到Endpoint?終結點路由必須注冊在UseRouting()?中間件之后。
三、官方常用中間件
1.異常/錯誤處理 當應用在開發環境中運行時:開發人員異常頁中間件 (UseDeveloperExceptionPage) 報告應用運行時錯誤。數據庫錯誤頁中間件報告數據庫運行時錯誤。當應用在生產環境中運行時:異常處理程序中間件 (UseExceptionHandler) 捕獲以下中間件中引發的異常。HTTP 嚴格傳輸安全協議 (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)。
掃描二維碼
獲取更多精彩
長按關注
總結
以上是生活随笔為你收集整理的Asp.Net Core 中间件应用实战中你不知道的那些事的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于 Redis 实现 CAS 操作
- 下一篇: 理解ASP.NET Core中的中间件