作為一個合格的搬磚程式設計師,小妹開啟了VS2019搭建了人生中的第一個.NetCore專案,根據IDE工具的提示搭建好專案後,在初始專案中我們會發現有這麼幾個檔案
內部檔案簡介:
Properties&launchSettings.json 是一個啟動組態檔,其用於應用的啟動準備工作,包括環境變數,開發埠等。
Program類是專案的啟動項,會為我們建立並初始化Web應用,並通過Startup類中的ConfigureServices和Configure方法,完成依賴注入和中介軟體管道的搭建。
Startup類
看到這,小妹有點懵了,啥是中介軟體?怎麼設定中介軟體?額…帶著問題找答案。百度了一下:
啥是中介軟體(Middleware)?
1.中介軟體是組裝到應用程式管道中以處理請求和響應的軟體。
2.每個元件選擇是否將請求傳遞給管道中的下一個元件。
3.每個元件可以在呼叫管道中的下一個元件之前和之後執行工作。
4.請求委託(Request delegates)用於構建請求管道,處理每個HTTP請求。
怎麼設定中介軟體?
請求委託使用Run,Map和Use擴充套件方法進行設定。單獨的請求委託可以以內聯匿名方法(稱為內聯中介軟體)指定,或者可以在可重用的類中定義它。這些可重用的類和內聯匿名方法是中介軟體或中介軟體元件。請求流程中的每個中介軟體元件都負責呼叫流水線中的下一個元件,如果適當,則負責連結短路。
將HTTP模組遷移到中介軟體解釋了ASP.NET Core和以前版本(ASP.NET)中的請求管道之間的區別,並提供了更多的中介軟體範例。
使用 IApplicationBuilder 建立中介軟體管道
ASP.NET Core請求流程由一系列請求委託組成,如下圖所示(執行流程遵循黑色箭頭):
每個委託可以在下一個委託之前和之後執行操作。委託還可以決定不將請求傳遞給下一個委託,這稱為請求管道的短路。短路通常是可取的,因為它避免了不必要的工作。例如,靜態檔案中介軟體可以返回一個靜態檔案的請求,並使管道的其餘部分短路。需要在管道早期呼叫例外處理委託,因此它們可以捕獲後面管道的異常。
最簡單的可能是ASP.NET Core應用程式建立一個請求的委託,處理所有的請求。此案例不包含實際的請求管道。相反,針對每個HTTP請求都呼叫一個匿名方法。
直接上程式碼吧!
上面文章說道中介軟體是應用程式管道中以處理請求和響應的軟體,主要用委託實現,請求委託使用Run,Map和Use擴充套件方法進行設定
一、app.Run
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.Run(async context =>
{
await context.Response.WriteAsync("I'm Run1\r\n");
});
app.Run(async context =>
{
await context.Response.WriteAsync("I'm Run2\r\n");
});
}
執行IIS發現只執行了第一個中介軟體
說明確實在第一個app.Run終止了管道
結論:Run方法是一個約定, 並且一些中介軟體元件可能暴露在管道末端執行的或者不執行下一個中介軟體時可以使用Run [Middleware]方法
二、app.Use
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.Use(async (context, next) =>
{
await context.Response.WriteAsync("I'm Use1\r\n");
});
app.Run(async context =>
{
await context.Response.WriteAsync("I'm Run2\r\n");
});
}
執行結果,怎麼肥事??不是說Use是內聯中介軟體嗎?為啥沒有執行下一個中介軟體的方法??
仔細看以上的程式碼段,Use方法比Run方法多了一個引數next,next參數列示管道中的下一個委託,沒有呼叫next.Invoke();尾端的Middleware即Run方法內沒有執行。我們再修改程式碼。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.Use(async (context, next) =>
{
await context.Response.WriteAsync("I'm Use1\r\n");
await next.Invoke();
});
app.Run(async context =>
{
await context.Response.WriteAsync("I'm Run2\r\n");
});
}
執行結果:執行了兩個委託
總結:使用Use方法,而沒有呼叫next.Invoke(),Use的效果與Run的效果是一致的。呼叫next.Invoke()後Use與Run程式碼段都被執行了。需要注意的是,管道中可以增加多個middleware(中介軟體),他們是按順序執行的,執行的順序與在Configure方法中程式碼的順序是一致的。
三、Map和MapWhen
Map比較不同,它將Middleware(中介軟體)新增到管道中,它是在管道中增加了分支。通過影射路徑的方式,增加管道分支。我們保留上面例子,並增加程式碼。如下:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.Use(async (context, next) =>
{
await context.Response.WriteAsync("I'm Use1\r\n");
await next.Invoke();
});
app.Map("/maptest", MapTest);//對映路徑存取指定的Middleware
app.Run(async context =>
{
await context.Response.WriteAsync("I'm Run2\r\n");
});
}
private static void MapTest(IApplicationBuilder app) {
app.Use(async (context,next)=> {
await context.Response.WriteAsync("this is maptest \r\n");
await next.Invoke();
});
}
啟動iis,在地址後面增加對映的地址如:https://localhost:44301/maptest,執行結果:
maptest分支被執行了
MapWhen:顧名思義滿足條件的情況下執行相應的方法
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.Use(async (context, next) =>
{
await context.Response.WriteAsync("I'm Use1\r\n");
await next.Invoke();
});
//app.Map("/maptest", MapTest);//對映路徑存取指定的Middleware
//如果有URL中的引數包含了zz,滿足這個條件,就執行MapTest
app.MapWhen(context=> { return context.Request.Query.ContainsKey("zz"); }, MapTest);
app.Run(async context =>
{
await context.Response.WriteAsync("I'm Run2\r\n");
});
}
private static void MapTest(IApplicationBuilder app) {
app.Use(async (context,next)=> {
await context.Response.WriteAsync("this is maptest \r\n");
await next.Invoke();
});
}
如果有URL中的引數包含了zz,滿足這個條件,就執行MapTest,地址:https://localhost:44301/?zz=1,執行結果:
通過以上的操作,小妹好像已經瞭解了什麼是管道,什麼是中介軟體,ASP.NET Core提供了附帶中介軟體元件,如下:
中介軟體 | 描述 |
---|---|
Authentication | 提供身份驗證支援 |
CORS | 設定跨域資源共用 |
Response Caching | 提供快取響應支援 |
Response Compression | 提供響應壓縮支援 |
Session | 提供使用者對談管理 |
Static Files | 為靜態檔案和目錄瀏覽提供服務提供支援 |
URL Rewriting Middleware | 用於重寫 Url,並將請求重定向的支援 |
好了,有啥總結的不好的,請各位大神多多指教。回家!
.Net技術交流群:274407988,歡迎大家進群交流學習。