作為一個合格的搬磚程式員,小妹打開了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,歡迎大家進群交流學習,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/203674.html
標籤:java
上一篇:計算機專業畢業設計億點建議
下一篇:一名新手程式員的學習規劃
