1. 程式人生 > >asp .net core 中介軟體

asp .net core 中介軟體

### 前言 對中介軟體的一個概況,在《重新整理.net core 計1400篇》系列後面會深入。 ### 正文 #### 什麼是中介軟體呢? 其實中介軟體這個概念來源於分散式,當然這是一個狹隘的概念了,現在中介軟體概念就非常廣泛了。 ![](https://img2020.cnblogs.com/blog/1289794/202008/1289794-20200827153316847-819628525.png) 官網給出了這樣一張圖,這張圖認為從請求到響應過程中間都是中介軟體,包括我們認為的路由。 看一段node程式碼: ``` var http = require("http"); http.createServer(function(req,res){ res.writeHead(200,{"Content-type":"text/blain"}); res.write("Hello NodeJs"); res.end(); }).listen(8888); ``` 沒有學過node 也是ok的,從字面意思就是建立了一個http服務,然後埠是80。 createServer 可以傳入一個方法,中間有兩個引數,一個引數是req,另一個引數就是res。 其實就是這麼回事,我們寫的就是這個這個方法裡面的程式碼,至於,你想拿到req的什麼引數,或者給res寫入什麼資訊,這些都是中介軟體的範疇。 那麼問題來了,問什麼叫做中介軟體呢?從語文的層面上理解,那就是分開的,一件一件的。 把這件要執行的這些封裝成一個一個模組,那麼這些模組,這些可以通過呼叫next執行下一個模組,同樣,如果不呼叫,那麼中介軟體模組就會中斷,因為有時候真的需要中斷,比如說許可權中介軟體, 檢查到許可權不符合直接返回讓其跳轉到許可權頁面,剩下的模組也用不到。 ``` 用 Use 將多個請求委託連結在一起。 next 引數表示管道中的下一個委託。 可通過不呼叫 next 引數使管道短路。 當委託不將請求傳遞給下一個委託時,它被稱為“讓請求管道短路”。 通常需要短路,因為這樣可以避免不必要的工作。 ``` 下圖為asp .net core 中預設的中介軟體順序,當然可以自己修改,但是這是一種推薦做法。 ![](https://img2020.cnblogs.com/blog/1289794/202008/1289794-20200827162305647-1762025349.png) 挺合理的一個東西,一開始就填入了異常處理機制。 然後是強制https 轉換->重定向->靜態資原始檔->路由->是否跨域->認證->授權->我們自己自定義需求的。 因為這個endpoint 是不建議我們修改的,當然我們可以修改原始碼中,畢竟開源了,but not must。 官網中同樣給了我們這個endpoint 做了什麼,其實就是官方自己封裝了一些中介軟體。 ![](https://img2020.cnblogs.com/blog/1289794/202008/1289794-20200827163209315-778990646.png) 當然我們也可以進行對endpoint自我的調整,因為可能使用不同的模板引擎: ``` app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); ``` 從上面得到一個推薦的中介軟體註冊來看,認證和授權在靜態檔案之後,那麼我們知道我們的資源時需要授權來保護的。 那麼如何保護靜態資源呢?這後面會有專門的一章實踐一下,看下是什麼原理。 好的,那麼看一下我們如何自定義中介軟體吧,也就是實踐一下下面這種圖。 ![](https://img2020.cnblogs.com/blog/1289794/202008/1289794-20200829150503047-1571680501.png) Middleware1 ``` public class Middleware1 { public readonly RequestDelegate _next; public Middleware1(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext context) { Console.WriteLine("Middleware1"); await _next(context); await context.Response.WriteAsync("Middleware1"); } } ``` ``` public class Middleware2 { public readonly RequestDelegate _next; public Middleware2(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext context) { Console.WriteLine("Middleware2"); await _next(context); await context.Response.WriteAsync("Middleware2"); } } ``` Middleware3 ``` public class Middleware3 { public readonly RequestDelegate _next; public Middleware3(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext context) { Console.WriteLine("Middleware3"); await _next(context); await context.Response.WriteAsync("Middleware3"); } } ``` 擴充套件方法: ``` public static class Middleware1MiddlewareExtensions { public static IApplicationBuilder UserMiddleware1(this IApplicationBuilder builder) { return builder.UseMiddleware(); } public static IApplicationBuilder UserMiddleware2(this IApplicationBuilder builder) { return builder.UseMiddleware(); } public static IApplicationBuilder UserMiddleware3(this IApplicationBuilder builder) { return builder.UseMiddleware(); } } ``` 加入中介軟體佇列: ``` app.UserMiddleware1(); app.UserMiddleware2(); app.UserMiddleware3(); ``` request 順序 ![](https://img2020.cnblogs.com/blog/1289794/202008/1289794-20200829150356488-1600970865.png) response 順序 ![](https://img2020.cnblogs.com/blog/1289794/202008/1289794-20200829150425628-393825894.png) 這其實就是一種職責鏈模式,每個中介軟體確定是否該需求是否要下一級處理,同樣會產生一個處理