最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解ASP.NET Core中間件Middleware

 更新時(shí)間:2022年01月13日 16:30:58   作者:曉晨Master  
本文詳細(xì)講解了ASP.NET Core中間件Middleware,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

本文為官方文檔譯文,官方文檔現(xiàn)已非機(jī)器翻譯 https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/middleware/?view=aspnetcore-2.1

什么是中間件(Middleware)?

中間件是組裝到應(yīng)用程序管道中以處理請(qǐng)求和響應(yīng)的軟件。 每個(gè)組件:

  • 選擇是否將請(qǐng)求傳遞給管道中的下一個(gè)組件。
  • 可以在調(diào)用管道中的下一個(gè)組件之前和之后執(zhí)行工作。

請(qǐng)求委托(Request delegates)用于構(gòu)建請(qǐng)求管道,處理每個(gè)HTTP請(qǐng)求。

請(qǐng)求委托使用Run,MapUse擴(kuò)展方法進(jìn)行配置。單獨(dú)的請(qǐng)求委托可以以內(nèi)聯(lián)匿名方法(稱為內(nèi)聯(lián)中間件)指定,或者可以在可重用的類中定義它。這些可重用的類和內(nèi)聯(lián)匿名方法是中間件或中間件組件。請(qǐng)求流程中的每個(gè)中間件組件都負(fù)責(zé)調(diào)用流水線中的下一個(gè)組件,如果適當(dāng),則負(fù)責(zé)鏈接短路。

將HTTP模塊遷移到中間件解釋了ASP.NET Core和以前版本(ASP.NET)中的請(qǐng)求管道之間的區(qū)別,并提供了更多的中間件示例。

使用 IApplicationBuilder 創(chuàng)建中間件管道

ASP.NET Core請(qǐng)求流程由一系列請(qǐng)求委托組成,如下圖所示(執(zhí)行流程遵循黑色箭頭):

每個(gè)委托可以在下一個(gè)委托之前和之后執(zhí)行操作。委托還可以決定不將請(qǐng)求傳遞給下一個(gè)委托,這稱為請(qǐng)求管道的短路。短路通常是可取的,因?yàn)樗苊饬瞬槐匾墓ぷ?。例如,靜態(tài)文件中間件可以返回一個(gè)靜態(tài)文件的請(qǐng)求,并使管道的其余部分短路。需要在管道早期調(diào)用異常處理委托,因此它們可以捕獲后面管道的異常。

最簡(jiǎn)單的可能是ASP.NET Core應(yīng)用程序建立一個(gè)請(qǐng)求的委托,處理所有的請(qǐng)求。此案例不包含實(shí)際的請(qǐng)求管道。相反,針對(duì)每個(gè)HTTP請(qǐng)求都調(diào)用一個(gè)匿名方法。

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello, World!");
        });
    }
}

第一個(gè) app.Run 委托終止管道。

有如下代碼:

通過瀏覽器訪問,發(fā)現(xiàn)確實(shí)在第一個(gè)app.Run終止了管道。

您可以將多個(gè)請(qǐng)求委托與app.Use連接在一起。 next參數(shù)表示管道中的下一個(gè)委托。 (請(qǐng)記住,您可以通過不調(diào)用下一個(gè)參數(shù)來結(jié)束流水線。)通??梢栽谙乱粋€(gè)委托之前和之后執(zhí)行操作,如下例所示:

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.Use(async (context, next) =>
	        {
				await context.Response.WriteAsync("進(jìn)入第一個(gè)委托 執(zhí)行下一個(gè)委托之前\r\n");
				//調(diào)用管道中的下一個(gè)委托
		        await next.Invoke();
		        await context.Response.WriteAsync("結(jié)束第一個(gè)委托 執(zhí)行下一個(gè)委托之后\r\n");
			});
	        app.Run(async context =>
	        {
		        await context.Response.WriteAsync("進(jìn)入第二個(gè)委托\(zhòng)r\n");
				await context.Response.WriteAsync("Hello from 2nd delegate.\r\n");
		        await context.Response.WriteAsync("結(jié)束第二個(gè)委托\(zhòng)r\n");
			});
    }
}

使用瀏覽器訪問有如下結(jié)果:

可以看出請(qǐng)求委托的執(zhí)行順序是遵循上面的流程圖的。

注意:

響應(yīng)發(fā)送到客戶端后,請(qǐng)勿調(diào)用next.Invoke。 響應(yīng)開始之后,對(duì)HttpResponse的更改將拋出異常。 例如,設(shè)置響應(yīng)頭,狀態(tài)代碼等更改將會(huì)引發(fā)異常。在調(diào)用next之后寫入響應(yīng)體。

  • 可能導(dǎo)致協(xié)議違規(guī)。 例如,寫入超過content-length所述內(nèi)容長(zhǎng)度。
  • 可能會(huì)破壞響應(yīng)內(nèi)容格式。 例如,將HTML頁腳寫入CSS文件。

HttpResponse.HasStarted是一個(gè)有用的提示,指示是否已發(fā)送響應(yīng)頭和/或正文已寫入。

順序

Startup。Configure方法中添加中間件組件的順序定義了在請(qǐng)求上調(diào)用它們的順序,以及響應(yīng)的相反順序。 此排序?qū)τ诎踩裕阅芎凸δ苤陵P(guān)重要。

Startup.Configure方法(如下所示)添加了以下中間件組件:

  • 異常/錯(cuò)誤處理
  • 靜態(tài)文件服務(wù)
  • 身份認(rèn)證
  • MVC
public void Configure(IApplicationBuilder app)
{
    app.UseExceptionHandler("/Home/Error"); // Call first to catch exceptions
                                            								// thrown in the following middleware.

    app.UseStaticFiles();                   // Return static files and end pipeline.

    app.UseAuthentication();               // Authenticate before you access
                                           					// secure resources.

    app.UseMvcWithDefaultRoute();          // Add MVC to the request pipeline.
}

上面的代碼,UseExceptionHandler是添加到管道中的第一個(gè)中間件組件,因此它捕獲以后調(diào)用中發(fā)生的任何異常。

靜態(tài)文件中間件在管道中提前調(diào)用,因此可以處理請(qǐng)求和短路,而無需通過剩余的組件。 靜態(tài)文件中間件不提供授權(quán)檢查。 由其提供的任何文件,包括wwwroot下的文件都是公開的。

如果請(qǐng)求沒有被靜態(tài)文件中間件處理,它將被傳遞給執(zhí)行身份驗(yàn)證的Identity中間件(app.UseAuthentication)。 身份不會(huì)使未經(jīng)身份驗(yàn)證的請(qǐng)求發(fā)生短路。 雖然身份認(rèn)證請(qǐng)求,但授權(quán)(和拒絕)僅在MVC選擇特定的Razor頁面或控制器和操作之后才會(huì)發(fā)生。

授權(quán)(和拒絕)僅在MVC選擇特定的Razor頁面或Controller和Action之后才會(huì)發(fā)生。

以下示例演示了中間件順序,其中靜態(tài)文件的請(qǐng)求在響應(yīng)壓縮中間件之前由靜態(tài)文件中間件處理。 靜態(tài)文件不會(huì)按照中間件的順序進(jìn)行壓縮。 來自UseMvcWithDefaultRoute的MVC響應(yīng)可以被壓縮。

public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles();         // Static files not compressed
    app.UseResponseCompression();
    app.UseMvcWithDefaultRoute();
}

Use, Run, 和 Map

你可以使用Use,RunMap配置HTTP管道。Use方法可以使管道短路(即,可以不調(diào)用下一個(gè)請(qǐng)求委托)。Run方法是一個(gè)約定, 并且一些中間件組件可能暴露在管道末端運(yùn)行的Run [Middleware]方法。Map*擴(kuò)展用作分支管道的約定。映射根據(jù)給定的請(qǐng)求路徑的匹配來分支請(qǐng)求流水線,如果請(qǐng)求路徑以給定路徑開始,則執(zhí)行分支。

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>");
        });
    }
}

下表顯示了使用以前代碼的 http://localhost:19219 的請(qǐng)求和響應(yīng):

請(qǐng)求響應(yīng)
localhost:1234Hello from non-Map delegate.
localhost:1234/map1Map Test 1
localhost:1234/map2Map Test 2
localhost:1234/map3Hello from non-Map delegate.

當(dāng)使用Map時(shí),匹配的路徑段將從HttpRequest.Path中刪除,并為每個(gè)請(qǐng)求追加到Http Request.PathBase。

MapWhen根據(jù)給定謂詞的結(jié)果分支請(qǐng)求流水線。 任何類型為Func<HttpContext,bool>的謂詞都可用于將請(qǐng)求映射到管道的新分支。 在以下示例中,謂詞用于檢測(cè)查詢字符串變量分支的存在:

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>");
        });
    }
}

以下下表顯示了使用上面代碼 http://localhost:19219 的請(qǐng)求和響應(yīng):

請(qǐng)求響應(yīng)
localhost:1234Hello from non-Map delegate.
localhost:1234/?branch=1Branch used = master

Map支持嵌套,例如:

app.Map("/level1", level1App => {
       level1App.Map("/level2a", level2AApp => {
           // "/level1/level2a"
           //...
       });
       level1App.Map("/level2b", level2BApp => {
           // "/level1/level2b"
           //...
       });
   });

Map也可以一次匹配多個(gè)片段,例如:

app.Map("/level1/level2", HandleMultiSeg);

內(nèi)置中間件

ASP.NET Core附帶以下中間件組件:

中間件描述
Authentication提供身份驗(yàn)證支持
CORS配置跨域資源共享
Response Caching提供緩存響應(yīng)支持
Response Compression提供響應(yīng)壓縮支持
Routing定義和約束請(qǐng)求路由
Session提供用戶會(huì)話管理
Static Files為靜態(tài)文件和目錄瀏覽提供服務(wù)提供支持
URL Rewriting Middleware用于重寫 Url,并將請(qǐng)求重定向的支持

編寫中間件

中間件通常封裝在一個(gè)類中,并使用擴(kuò)展方法進(jìn)行暴露。 查看以下中間件,它從查詢字符串設(shè)置當(dāng)前請(qǐng)求的Culture:

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.Use((context, next) =>
        {
            var cultureQuery = context.Request.Query["culture"];
            if (!string.IsNullOrWhiteSpace(cultureQuery))
            {
                var culture = new CultureInfo(cultureQuery);

                CultureInfo.CurrentCulture = culture;
                CultureInfo.CurrentUICulture = culture;
            }

            // Call the next delegate/middleware in the pipeline
            return next();
        });

        app.Run(async (context) =>
        {
            await context.Response.WriteAsync(
                $"Hello {CultureInfo.CurrentCulture.DisplayName}");
        });

    }
}

您可以通過傳遞Culture來測(cè)試中間件,例如 http://localhost:19219/?culture=zh-CN

以下代碼將中間件委托移動(dòng)到一個(gè)類:

using Microsoft.AspNetCore.Http;
using System.Globalization;
using System.Threading.Tasks;

namespace Culture
{
    public class RequestCultureMiddleware
    {
        private readonly RequestDelegate _next;

        public RequestCultureMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public Task Invoke(HttpContext context)
        {
            var cultureQuery = context.Request.Query["culture"];
            if (!string.IsNullOrWhiteSpace(cultureQuery))
            {
                var culture = new CultureInfo(cultureQuery);

                CultureInfo.CurrentCulture = culture;
                CultureInfo.CurrentUICulture = culture;

            }

            // Call the next delegate/middleware in the pipeline
            return this._next(context);
        }
    }
}

以下通過IApplicationBuilder的擴(kuò)展方法暴露中間件:

using Microsoft.AspNetCore.Builder;

namespace Culture
{
    public static class RequestCultureMiddlewareExtensions
    {
        public static IApplicationBuilder UseRequestCulture(
            this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<RequestCultureMiddleware>();
        }
    }
}

以下代碼從Configure調(diào)用中間件:

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.UseRequestCulture();

        app.Run(async (context) =>
        {
            await context.Response.WriteAsync(
                $"Hello {CultureInfo.CurrentCulture.DisplayName}");
        });

    }
}

中間件應(yīng)該遵循顯式依賴原則,通過在其構(gòu)造函數(shù)中暴露其依賴關(guān)系。 中間件在應(yīng)用程序生命周期構(gòu)建一次。 如果您需要在請(qǐng)求中與中間件共享服務(wù),請(qǐng)參閱以下請(qǐng)求相關(guān)性。

中間件組件可以通過構(gòu)造方法參數(shù)來解析依賴注入的依賴關(guān)系。 UseMiddleware也可以直接接受其他參數(shù)。

每個(gè)請(qǐng)求的依賴關(guān)系

因?yàn)橹虚g件是在應(yīng)用程序啟動(dòng)時(shí)構(gòu)建的,而不是每個(gè)請(qǐng)求,所以在每個(gè)請(qǐng)求期間,中間件構(gòu)造函數(shù)使用的作用域生命周期服務(wù)不會(huì)與其他依賴注入類型共享。 如果您必須在中間件和其他類型之間共享作用域服務(wù),請(qǐng)將這些服務(wù)添加到Invoke方法的簽名中。 Invoke方法可以接受由依賴注入填充的其他參數(shù)。 例如:

public class MyMiddleware
{
    private readonly RequestDelegate _next;

    public MyMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext httpContext, IMyScopedService svc)
    {
        svc.MyProperty = 1000;
        await _next(httpContext);
    }
}

到此這篇關(guān)于ASP.NET Core中間件Middleware詳解的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • ASP.NET處理HTTP請(qǐng)求的流程:IHttpModule、IHttpHandler與管道事件

    ASP.NET處理HTTP請(qǐng)求的流程:IHttpModule、IHttpHandler與管道事件

    這篇文章介紹了ASP.NET處理HTTP請(qǐng)求的流程:IHttpModule、IHttpHandler與管道事件,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • WPF基本控件介紹

    WPF基本控件介紹

    這篇文章介紹了WPF的控件結(jié)構(gòu)及各種控件類型,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-01-01
  • Linux Ubuntu系統(tǒng)上手動(dòng)安裝.NET Core SDK的方法

    Linux Ubuntu系統(tǒng)上手動(dòng)安裝.NET Core SDK的方法

    .NET Core是一個(gè)開源通用的開發(fā)框架,支持跨平臺(tái),即支持在Window,macOS,Linux等系統(tǒng)上的開發(fā)和部署,并且可以在硬件設(shè)備,云服務(wù),和嵌入式/物聯(lián)網(wǎng)方案中進(jìn)行使用。下面這篇文章將給大家詳細(xì)介紹關(guān)于在Linux Ubuntu系統(tǒng)上手動(dòng)安裝.NET Core SDK的方法。
    2016-12-12
  • ASP.NET中Literal與Label控件的區(qū)別

    ASP.NET中Literal與Label控件的區(qū)別

    相信學(xué)ASP.NET的朋友們都會(huì)遇到Literal和Label到底該用那個(gè)的問題,Literal和Label到底有什么不同,其實(shí)簡(jiǎn)單的講就是Literal不會(huì)產(chǎn)生HTML代碼,而Label會(huì)產(chǎn)生一個(gè)span標(biāo)記,下面為大家詳細(xì)講解一下。
    2016-04-04
  • ASP.NET Calendar日歷(日期)控件使用方法

    ASP.NET Calendar日歷(日期)控件使用方法

    本文主要介紹Calendar日歷控件的各個(gè)屬性以及舉例演示Calendar控件的具體使用方法,希望對(duì)大家有所幫助。
    2016-04-04
  • 創(chuàng)建ASP.NET?Core?Web應(yīng)用程序并介紹項(xiàng)目模板

    創(chuàng)建ASP.NET?Core?Web應(yīng)用程序并介紹項(xiàng)目模板

    這篇文章介紹了創(chuàng)建ASP.NET?Core?Web應(yīng)用程序的方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-02-02
  • 部署ASP.NET?Core程序到Linux系統(tǒng)

    部署ASP.NET?Core程序到Linux系統(tǒng)

    這篇文章介紹了部署ASP.NET?Core程序到Linux系統(tǒng)的方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-03-03
  • .NET?6更新使.NET生態(tài)系統(tǒng)蛻變

    .NET?6更新使.NET生態(tài)系統(tǒng)蛻變

    微軟正式發(fā)布.NET最新長(zhǎng)期支持版本.NET?6,這個(gè)版本的更新重點(diǎn),除了C#和F#都有許多語言功能改進(jìn)之外,.NET?6終于集大成,成為跨瀏覽器、云計(jì)算、桌面、物聯(lián)網(wǎng)和移動(dòng)應(yīng)用程序的統(tǒng)一平臺(tái),性能也獲得大幅提升,并且更完整支持Arm64
    2022-01-01
  • ASP.NET中FileUpload文件上傳控件應(yīng)用實(shí)例

    ASP.NET中FileUpload文件上傳控件應(yīng)用實(shí)例

    本文主要介紹FileUpload文件上傳控件在實(shí)際開發(fā)中經(jīng)常遇到的問題并給出解決方法,希望對(duì)大家有所幫助。
    2016-04-04
  • c#中實(shí)現(xiàn)文件拖放打開的方法

    c#中實(shí)現(xiàn)文件拖放打開的方法

    向ListBox拖入一個(gè)文件,ListBox顯示該文件的路徑,然后單擊該路徑,點(diǎn)擊Open按鈕打開該文件
    2006-10-10

最新評(píng)論

郓城县| 荆门市| 绥棱县| 临澧县| 沭阳县| 黑龙江省| 大安市| 尼勒克县| 聊城市| 五指山市| 观塘区| 德保县| 含山县| 夏津县| 卫辉市| 禹州市| 临清市| 会泽县| 蒙自县| 康乐县| 镇赉县| 峨眉山市| 辉县市| 淄博市| 上思县| 台前县| 新津县| 拉孜县| 琼结县| 昭通市| 崇仁县| 伊金霍洛旗| 泾阳县| 嘉祥县| 同江市| 西青区| 化州市| 酒泉市| 星座| 庆城县| 新津县|