中間件是一種插入到管道上進行處理請求和響應的軟件;每一箇中間件組件具備下面的功能:session
請求委託(request delegate)是用於創建(build)請求管道的,請求委託能夠處理每一個Http的請求;app
請求委託被配置的方法有三種:Run、Map、Use 擴展方法;async
請求管道由一系列請求委託組成,一個調用一個;以下圖函數
每一個委託均可以在下一個委託以前和以後執行。異常處理的委託在管道中被儘早調用,由於它能夠捕獲到後面管道中發生的錯誤。ui
使用一個匿名函數處理每一個 Http 請求;而且使用的是 run ,它表示管道的結束,即最後一箇中間件,不會再傳遞到下一個中間件spa
public class Startup { public void Configure(IApplicationBuilder app) { app.Run(async context => { await context.Response.WriteAsync("Hello, World!"); }); } }
next 參數 表明管道中的下一個委託,能夠在下一個委託以前和以後進行處理;你也能夠不調用 next 參數,直接短路管道(即不會傳遞到下一個委託/中間件)。code
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."); }); } }
這裏的順序是指中間件被加到 Startup.Configure 方法的順序決定了中間件順序處理請求和逆序處理響應。因此,添加順序是很重要的orm
通常的應用中的 Startup.Configure 方法添加中間組件的順序:server
public void Configure(IApplicationBuilder app) { if (env.IsDevelopment()) { // When the app runs in the Development environment: // Use the Developer Exception Page to report app runtime errors. // Use the Database Error Page to report database runtime errors.
// 添加異常中間件以後,後面中間件發生的異常都會被捕獲
app.UseDeveloperExceptionPage(); app.UseDatabaseErrorPage(); } else { // When the app doesn't run in the Development environment: // Enable the Exception Handler Middleware to catch exceptions // thrown in the following middlewares. // Use the HTTP Strict Transport Security Protocol (HSTS) // Middleware. app.UseExceptionHandler("/Error"); app.UseHsts(); } // Use HTTPS Redirection Middleware to redirect HTTP requests to HTTPS.使用https重定向中間件來重定向http請求到https請求 app.UseHttpsRedirection(); // Return static files and end the pipeline. app.UseStaticFiles(); // Use Cookie Policy Middleware to conform to EU General Data // Protection Regulation (GDPR) regulations. app.UseCookiePolicy(); // Authenticate before the user accesses secure resources. app.UseAuthentication(); // If the app uses session state, call Session Middleware after Cookie // Policy Middleware and before MVC Middleware. app.UseSession(); // Add MVC to the request pipeline. app.UseMvc(); }
使用 Use , Run 和 Map 配置 HTTP 管道。中間件
Use 方法若是不調用next 就會形成短路;
一些中間件組件可能會暴露 Run [ Middleware ] 方法 在管道的結束處運行;
Map 擴展 主要用做一種分支管道的慣例:
Map* 根據這給出的請求路徑是否匹配來進入管道。
public class Startup { private static void HandleMapTest1(IApplicationBuilder app) { app.Run(async context => { await context.Response.WriteAsync("Map Test 1"); }); } private static void HandleMapTest2(IApplicationBuilder app) { app.Run(async context => { await context.Response.WriteAsync("Map Test 2"); }); } public void Configure(IApplicationBuilder app) { app.Map("/map1", HandleMapTest1); app.Map("/map2", HandleMapTest2); app.Run(async context => { await context.Response.WriteAsync("Hello from non-Map delegate. <p>"); }); } }
若是路徑匹配 /map1 ,則執行 HandleMapTest1;
若是路徑匹配 /map2 , 則執行 HandleMapTest2 ;
以下示例:
MapWhen 的用法
當知足某個條件時,執行
public class Startup { private static void HandleBranch(IApplicationBuilder app) { app.Run(async context => { var branchVer = context.Request.Query["branch"]; await context.Response.WriteAsync($"Branch used = {branchVer}"); }); } public void Configure(IApplicationBuilder app) { app.MapWhen(context => context.Request.Query.ContainsKey("branch"), HandleBranch); app.Run(async context => { await context.Response.WriteAsync("Hello from non-Map delegate. <p>"); }); } }
示例以下:
另外,map支持嵌套
app.Map("/level1", level1App => { level1App.Map("/level2a", level2AApp => { // "/level1/level2a" processing }); level1App.Map("/level2b", level2BApp => { // "/level1/level2b" processing }); });
並且,map支持每次匹配多個段
public class Startup { private static void HandleMultiSeg(IApplicationBuilder app) { app.Run(async context => { await context.Response.WriteAsync("Map multiple segments."); }); } public void Configure(IApplicationBuilder app) { app.Map("/map1/seg1", HandleMultiSeg); //此句示例 app.Run(async context => { await context.Response.WriteAsync("Hello from non-Map delegate."); }); } }
另外還有不少內置的中間件可供使用,可根據須要進行使用
參考網址:
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-2.2