小白开学Asp.Net Core 《七》
小白開(kāi)學(xué)Asp.Net Core 《七》
? ? ? ? ? ? ? ? ? ? ? — — 探究中間件(MiddleWare)
1、何為中間件?
中間件是組裝到應(yīng)用程序管道中以處理請(qǐng)求和響應(yīng)的家伙,管道中的每個(gè)組件都要滿足以下兩個(gè)條件
- 選擇是否將請(qǐng)求傳遞給管道中的下一個(gè)組件 
- 可以在調(diào)用管道中的下一個(gè)組件之前和之后執(zhí)行工作。 
2、中間件的本質(zhì)
在.Net Core 中,中間件的本質(zhì)就是一個(gè)Func的委托,其中RequestDelegate的本質(zhì)也是一個(gè)委托(常常聽(tīng)人說(shuō),要想進(jìn)階到高級(jí)開(kāi)發(fā),必須要搞清楚委托。看來(lái)不得不搞懂委托了,本文默認(rèn)您已搞懂了?如果沒(méi)搞懂怎么辦呢?不要緊,抽時(shí)間搞懂就行了),讓我們來(lái)看看它的定義(證明我沒(méi)在吹牛)
? ? ? 再來(lái)看看?RequestDelegate
? ? ??
? ? 接下來(lái)我嘗試著解釋下Func這個(gè)委托。我們都知道 Func 這個(gè) 內(nèi)置的委托
? ? ?(我只截了與本文相關(guān)的一張圖)
通過(guò)Func 這個(gè)截圖的定義來(lái)看,它接受一個(gè) T? 返回一個(gè) TResult ,結(jié)合我們前面說(shuō)的中間件來(lái)說(shuō),它接受一個(gè)RequestDelegate,返回一個(gè)RequestDelegate。也就是說(shuō),每一個(gè)中間件Func的傳入?yún)?shù)RequestDelegate是下一個(gè)中間件的返回值,同時(shí)每一個(gè)中間件Func的返回值是前一個(gè)中間件的傳入?yún)?shù)。這樣就構(gòu)成了一串中間件鏈表,每當(dāng)一個(gè)請(qǐng)求過(guò)來(lái),都會(huì)按照中間件的注冊(cè)順序依次執(zhí)行RequestDelegate中的內(nèi)容,這就構(gòu)成了ASP.NET Core中的請(qǐng)求管道。(好好理解這句話,這是真理呀,開(kāi)個(gè)玩笑,這是我本人這么認(rèn)為的。)
這里得上一張經(jīng)典的圖配合上一句真理來(lái)理解就不那么難了。
好,我們現(xiàn)在知道了Http請(qǐng)求處理管理是由多個(gè)Middleware組成的。可我們上面從沒(méi)提到Http相關(guān)的信息,現(xiàn)在讓我們看看它們是如何發(fā)生戀愛(ài)(產(chǎn)生關(guān)系的)?
仔細(xì)看了前文的話,大家應(yīng)該注意到RequestDelegate的定義(仔細(xì)回想下),哎 估計(jì)你們都想起來(lái)了,對(duì)還是上圖我們?cè)賹W(xué)習(xí)下? ? ?
? ? ? ? ? ?
?這次我把這個(gè)家伙的定義到截到圖里,我們嘗試著翻譯下:A function that can process an HTTP request. 我將它翻譯為:一個(gè)能夠處理HTTP請(qǐng)求的 function(函數(shù)、方法)。是不是大家突然間知道了,原來(lái)是這個(gè)家伙讓它們與HTTP關(guān)聯(lián)在一起的(產(chǎn)生了戀情)。
?好,如果你不信的話就讓我們來(lái)看看 HttpContext 這個(gè)家伙。為什么要看這個(gè)家伙呢,因?yàn)樗?RequestDelegate 這個(gè)委托 接受的參數(shù)。
? ? 好了,這里不得不相信,.Net Core 的 Http 請(qǐng)求處理管道是由多個(gè)Middleware 組成的,并且 Middleware 與 Http 請(qǐng)求上下文 僅僅的關(guān)聯(lián)在一起。
?
使用Use、Run和Map 配置HTTP管道。
3、Use、Run和Map
您可以使用Use、Run和Map 來(lái)配置HTTP管道,但各方法針對(duì)構(gòu)建的中間件作用不同.
Use:Use[Middleware]中間件負(fù)責(zé)調(diào)用管道中的下一個(gè)中間件,也可使管道短路(即不調(diào)用 next 請(qǐng)求委托)。
Run:Run[Middleware]是一種約定,一些中間件組件可能會(huì)公開(kāi)在管道末端運(yùn)行的Run[Middleware]方法。
Map:Map擴(kuò)展用作約定來(lái)創(chuàng)建管道分支, Map*創(chuàng)建請(qǐng)求管道分支是基于給定請(qǐng)求路徑的匹配項(xiàng)。
public class Startup { public void Configure(IApplicationBuilder app) { app.Use(async (context, next) => { // Do work that doesn't write to the Response. await next.Invoke(); // Do logging or other work that doesn't write to the Response. }); app.Run(async context => { await context.Response.WriteAsync("Hello from 2nd delegate."); }); } }Use將多個(gè)請(qǐng)求委托鏈接在一起,next 參數(shù)表示管道中的下一個(gè)委托,可通過(guò)不 調(diào)用 next 參數(shù)使管道短路。?通常可在下一個(gè)委托前后執(zhí)行操作。
當(dāng)委托不將請(qǐng)求傳遞給下一個(gè)委托時(shí),它被稱(chēng)為“讓請(qǐng)求管道短路” 。?通常需要短路,因?yàn)檫@樣可以避免不必要的工作。
?Run委托終止管道。意思就是說(shuō),使用的Run 委托后,Run 下面的所有方法將不會(huì)被執(zhí)行。
public class Startup { private static void HandleMap1(IApplicationBuilder app) { app.Run(async context => { await context.Response.WriteAsync("Map 1"); }); } private static void HandleMap2(IApplicationBuilder app) { app.Run(async context => { await context.Response.WriteAsync("Map 2"); }); } public void Configure(IApplicationBuilder app) { app.Map("/map1", HandleMap1); app.Map("/map2", HandleMap2); app.Run(async context => { await context.Response.WriteAsync("Hello from End Map delegate."); }); } }執(zhí)行與響應(yīng)如下:
| 請(qǐng)求 | 響應(yīng) | 
| localhost:5000 | Hello from End Map delegate. | 
| localhost:5000/map1 | Map 1 | 
| localhost:5000/map2 | Map 2 | 
?
4、總結(jié)
1)、中間件(Middleware)是由IApplicationBuilder來(lái)構(gòu)建的
2)、所有的代碼截圖都是?IApplicationBuilder F12后看到的
5、說(shuō)明
參考文章:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/middleware/?view=aspnetcore-3.0
總結(jié)
以上是生活随笔為你收集整理的小白开学Asp.Net Core 《七》的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: windows container 踩坑
- 下一篇: aspnetcore 实现简单的伪静态化
