.NET Core开发实战(第21课:中间件:掌控请求处理过程的关键)--学习笔记(上)...
21 | 中間件:掌控請(qǐng)求處理過程的關(guān)鍵
這一節(jié)講解一下如何通過中間件來管理請(qǐng)求處理過程
中間件工作原理
next 表示后面有一個(gè)委托,每一層每一層套下去可以在任意的中間件來決定在后面的中間件之前執(zhí)行什么,或者說在所有中間件執(zhí)行完之后執(zhí)行什么
整個(gè)中間件的處理過程實(shí)際上有兩個(gè)核心對(duì)象:
IApplicationBuilder
RequestDelegate:處理整個(gè)請(qǐng)求的委托
源碼鏈接:
https://github.com/witskeeper/geektime/tree/master/samples/MiddlewareDemo
IApplicationBuilder
namespace Microsoft.AspNetCore.Builder {public interface IApplicationBuilder{IServiceProvider ApplicationServices { get; set; }IDictionary<string, object> Properties { get; }IFeatureCollection ServerFeatures { get; }// 最終它會(huì) Build 返回一個(gè)委托// 這個(gè)委托就是把所有的中間件串起來之后,合并成一個(gè)委托方法// 這個(gè)方法的入?yún)⒖梢钥聪路轿械亩xRequestDelegate Build();IApplicationBuilder New();// 它可以讓我們?nèi)プ?cè)我們的中間件,把委托注冊(cè)進(jìn)去,每一個(gè)委托的入?yún)⒁彩且粋€(gè)委托// 這也就意味著可以把這些委托注冊(cè)成一個(gè)鏈,就像上面的圖顯示的那樣IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware);} }委托的定義
namespace Microsoft.AspNetCore.Http {// 委托的入?yún)⑹?HttpContext,所有的注冊(cè)中間件的委托實(shí)際上都是對(duì) HttpContext 的處理public delegate Task RequestDelegate(HttpContext context); }接著讓我們看一下應(yīng)用程序里面是怎么讓它工作的?
之前課程講過 Configure 方法是用來注冊(cè)中間件的
app.UseMyMiddleware();app.UseHttpsRedirection();app.UseRouting();app.UseAuthorization();app.UseEndpoints(endpoints => {endpoints.MapControllers(); });根據(jù)剛才流程圖表示的話,實(shí)際上中間件的執(zhí)行順序是跟注冊(cè)順序有關(guān)系的,最早注冊(cè)的中間件它的權(quán)力是最大的,它可以越早的發(fā)生作用
中間件的注冊(cè)實(shí)際上不僅僅是有上面展示的已有內(nèi)置的中間件,實(shí)際上還可以用注冊(cè)委托的方法來注冊(cè)我們的邏輯
app.Use(async (context, next) => {await context.Response.WriteAsync("Hello"); });因?yàn)檫@個(gè)中間件注冊(cè)最早,而且不對(duì)后續(xù)的 next 做任何操作,所以啟動(dòng)之后無論輸入什么都會(huì)輸出 Hello
如果需要后續(xù)的中間件執(zhí)行,那就意味著需要調(diào)用 next,可以在中間件執(zhí)行之后再次 Hello 一次
app.Use(async (context, next) => {await context.Response.WriteAsync("Hello");await next();await context.Response.WriteAsync("Hello2"); });啟動(dòng)程序報(bào)錯(cuò):
System.InvalidOperationException: Headers are read-only, response has already started.意味著一旦應(yīng)用程序已經(jīng)對(duì) Response 輸出內(nèi)容,我們就不能對(duì) header 進(jìn)行操作了,但是可以在 Response 后續(xù)繼續(xù)寫出信息
app.Use(async (context, next) => {//await context.Response.WriteAsync("Hello");await next();await context.Response.WriteAsync("Hello2"); });實(shí)際上除了 Use 這種方式的話,還有 Map 的方式
app.Map("/abc", abcBuilder => {abcBuilder.Use(async (context, next) =>{//await context.Response.WriteAsync("Hello");await next();await context.Response.WriteAsync("Hello2");}); });啟動(dòng)程序不會(huì)直接看到 Hello 輸出,如果把地址改為 localhost:5001/abc,我們的輸出就會(huì)變成 Hello2
也就是說當(dāng)我們需要對(duì)特定的路徑進(jìn)行指定中間件的時(shí)候可以這樣做
總結(jié)
以上是生活随笔為你收集整理的.NET Core开发实战(第21课:中间件:掌控请求处理过程的关键)--学习笔记(上)...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从Java转向.NET/C#,Are Y
- 下一篇: asp.net ajax控件工具集 Au