Asp.Net Core 中间件应用实战中你不知道的那些事
一、概述
這篇文章主要分享Endpoint?終結(jié)點(diǎn)路由的中間件的應(yīng)用場景及實(shí)踐案例,不講述其工作原理,如果需要了解工作原理的同學(xué), 可以點(diǎn)擊查看以下兩篇解讀文章:
?Asp.Net Core EndPoint 終結(jié)點(diǎn)路由工作原理解讀?ASP.NET CORE 管道模型及中間件使用解讀
1.1 中間件(Middleware)的作用
我們知道,任何的一個(gè)web框架都是把http請求封裝成一個(gè)管道,每一次的請求都是經(jīng)過管道的一系列操作,最終到達(dá)我們寫的代碼中。那么中間件就是在應(yīng)用程序管道中的一個(gè)組件,用來攔截請求過程進(jìn)行一些其他處理和響應(yīng)。中間件可以有很多個(gè),每一個(gè)中間件都可以對管道中的請求進(jìn)行攔截,它可以決定是否將請求轉(zhuǎn)移給下一個(gè)中間件。
asp.net core 提供了IApplicationBuilder接口來讓把中間件注冊到asp.net的管道請求當(dāng)中去,中間件是一個(gè)典型的AOP應(yīng)用。下面是一個(gè)微軟官方的一個(gè)中間件管道請求圖:
1.2 中間件和過濾器的區(qū)別
Filter是延續(xù)ASP.NET MVC的產(chǎn)物,同樣保留了五種的Filter,分別是Authorization Filter、Resource Filter、Action Filter、Exception Filter及Result Filter。具體可以查看我上次分享的一篇Asp.Net Core Filter 深入淺出的那些事-AOP的文章.
根據(jù)描述,可以看出中間件和過濾器的功能類似,那么他們有什么區(qū)別?為什么又要搞一個(gè)中間件呢?其實(shí),過濾器和中間件他們的關(guān)注點(diǎn)是不一樣的,也就是說職責(zé)不一樣,干的事情就不一樣。
同作為兩個(gè)AOP利器,Filter(過濾器)更貼合業(yè)務(wù),它關(guān)注于應(yīng)用程序本身,比如你看ActionFilter?和?ResultFilter,它都直接和你的Action,ActionResult交互了,是不是離你很近的感覺,那我有一些比如對我的輸出結(jié)果進(jìn)行格式化,對我的請求的ViewModel進(jìn)行數(shù)據(jù)驗(yàn)證啦,肯定就是用Filter無疑了。它是MVC的一部分,它可以攔截到你Action上下文的一些信息,而中間件是沒有這個(gè)能力的。
可以看到,每一個(gè)中間件都都可以在請求之前和之后進(jìn)行操作。請求處理完成之后傳遞給下一個(gè)請求
1.3 中間件的使用場景
那么,何時(shí)使用中間件呢?我的理解是在我們的應(yīng)用程序當(dāng)中和業(yè)務(wù)關(guān)系不大的一些需要在管道中做的事情可以使用,比如身份驗(yàn)證,Session存儲,日志記錄等。其實(shí)我們的 Asp.net core項(xiàng)目中本身已經(jīng)包含了很多個(gè)中間件。比如 身份認(rèn)證中間件?UseAuthorization()等系列.
二、中間件實(shí)戰(zhàn)
需求場景:通過后端記錄每一次的訪問請求日志,同時(shí)需要根據(jù)需要排除一些Controller?或者Action?不記錄請求的日志信息。
思考:經(jīng)過分析我需要?jiǎng)?chuàng)建一個(gè)全局的中間件進(jìn)行攔截路由,并且寫入日志;同時(shí)需要添加一個(gè)特性Attribute?進(jìn)行標(biāo)注那些Controller或者Action?不需要進(jìn)行日志記錄。
我們來創(chuàng)建LogsMiddleware?中間件代碼,代碼如下:
NoLogsAttriteFilter?過濾器代碼如下:
public class NoLogsAttriteFilter : Attribute {/// <summary>/// 這里加這個(gè)主要是把獲取到的信息在中間件中打印出來///,區(qū)分中間件的攔截用處/// </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?控制器中的兩個(gè)Action 代碼如下::
// 訪問該路由會記錄訪問日志 public IActionResult Index() {return?View(); }//訪問該路由不會記錄訪問日志 [NoLogsAttriteFilter("Manage 不需要記錄訪問日志")] public IActionResult Manage() {return?View(); }這樣就自定義日志中間件就已經(jīng)完成了我上面的需求,不依賴于任何業(yè)務(wù)獨(dú)立存在于系統(tǒng)中;從代碼中我們可以看到中間件通過context.Features.Get<IEndpointFeature>()?.Endpoint;?方法獲得終結(jié)點(diǎn)路由方式進(jìn)行匹配, 自定義中間件教程文章請點(diǎn)擊自定義中間件官方教程[4]?一文。
現(xiàn)在我們再來印證下我上一篇關(guān)于?Asp.Net Core EndPoint 終結(jié)點(diǎn)路由工作原理解讀?一文 中提及到UseRouting()?中間件是遍歷所有的Endpoint?終結(jié)點(diǎn)路由以匹配當(dāng)前請求的?Endpoint?終結(jié)點(diǎn)路由一說,我把注冊LogsMiddleware中間件和UseRouting()?路由中間件代碼順序調(diào)整一下,代碼如下:
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?}");}); }再來看看運(yùn)行調(diào)試的結(jié)果如圖:
從調(diào)試的結(jié)果圖中可以看出?endpoint?變量是 null;所有需要使用到Endpoint?終結(jié)點(diǎn)路由必須注冊在UseRouting()?中間件之后。
三、官方常用中間件
1.異常/錯(cuò)誤處理 當(dāng)應(yīng)用在開發(fā)環(huán)境中運(yùn)行時(shí):開發(fā)人員異常頁中間件 (UseDeveloperExceptionPage) 報(bào)告應(yīng)用運(yùn)行時(shí)錯(cuò)誤。數(shù)據(jù)庫錯(cuò)誤頁中間件報(bào)告數(shù)據(jù)庫運(yùn)行時(shí)錯(cuò)誤。當(dāng)應(yīng)用在生產(chǎn)環(huán)境中運(yùn)行時(shí):異常處理程序中間件 (UseExceptionHandler) 捕獲以下中間件中引發(fā)的異常。HTTP 嚴(yán)格傳輸安全協(xié)議 (HSTS) 中間件 (UseHsts) 添加 Strict-Transport-Security 標(biāo)頭。2.HTTPS 重定向中間件 (UseHttpsRedirection) 將 HTTP 請求重定向到 HTTPS。3.靜態(tài)文件中間件 (UseStaticFiles) 返回靜態(tài)文件,并簡化進(jìn)一步請求處理。4.Cookie 策略中間件 (UseCookiePolicy) 使應(yīng)用符合歐盟一般數(shù)據(jù)保護(hù)條例 (GDPR) 規(guī)定。5.用于路由請求的路由中間件 (UseRouting)。6.身份驗(yàn)證中間件 (UseAuthentication) 嘗試對用戶進(jìn)行身份驗(yàn)證,然后才會允許用戶訪問安全資源。7.用于授權(quán)用戶訪問安全資源的授權(quán)中間件 (UseAuthorization)。8.會話中間件 (UseSession) 建立和維護(hù)會話狀態(tài)。如果應(yīng)用使用會話狀態(tài),請?jiān)?Cookie 策略中間件之后和 MVC 中間件之前調(diào)用會話中間件。9.用于將?Razor Pages?終結(jié)點(diǎn)添加到請求管道的終結(jié)點(diǎn)路由中間件(帶有 MapRazorPages 的?UseEndpoints)。
掃描二維碼
獲取更多精彩
長按關(guān)注
總結(jié)
以上是生活随笔為你收集整理的Asp.Net Core 中间件应用实战中你不知道的那些事的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于 Redis 实现 CAS 操作
- 下一篇: 理解ASP.NET Core中的中间件