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