asp .net core 中介軟體
阿新 • • 發佈:2020-08-29
### 前言
對中介軟體的一個概況,在《重新整理.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)
這其實就是一種職責鏈模式,每個中介軟體確定是否該需求是否要下一級處理,同樣會產生一個處理