每个组件:

  • 选择是否将请求传递到管道中的下一个组件。
  • 可在管道中的下一个组件前后执行工作。

请求委托处理每个 HTTP 请求。

当中间件短路时,它被称为“终端中间件” ,因为它阻止中间件进一步处理请求。

将 HTTP 处理程序和模块迁移到 ASP.NET Core 中间件介绍了 ASP.NET Core 和 ASP.NET 4.x 中请求管道之间的差异,并提供了更多的中间件示例。

使用 IApplicationBuilder 创建中间件管道

沿黑色箭头执行。

ASP.NET Core3.1 中间件middleware讲解

应尽早在管道中调用异常处理委托,这样它们就能捕获在管道的后期阶段发生的异常。

调用单个匿名函数以响应每个 HTTP 请求。

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

通常可在下一个委托前后执行操作,如以下示例所示:

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.Use(async (context, next) =>
        {
            // Do work that doesn't write to the Response.
            await next.Invoke();
            // Do logging or other work that doesn't write to the Response.
        });
 
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello from 2nd delegate.");
        });
    }
}

不过,请参阅下面有关尝试对已发送的响应执行写入操作的警告。

警告

调用 next 后写入响应正文:

  • 例如,写入的长度超过规定的 Content-Length
  • 例如,向 CSS 文件中写入 HTML 页脚。

HasStarted 是一个有用的提示,指示是否已发送标头或已写入正文。

 

某些中间件组件可能会公开在管道末尾运行的 Run[Middleware] 方法:

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.Use(async (context, next) =>
        {
            // Do work that doesn't write to the Response.
            await next.Invoke();
            // Do logging or other work that doesn't write to the Response.
        });
 
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello from 2nd delegate.");
        });
    }
}

如果在 Run 委托之后添加了另一个 Use 或 Run 委托,则不会调用该委托。

中间件顺序

此顺序对于安全性、性能和功能至关重要。

下面的 Startup.Configure 方法按照建议的顺序增加与安全相关的中间件组件:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }
 
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    // app.UseCookiePolicy();
 
    app.UseRouting();
    // app.UseRequestLocalization();
    // app.UseCors();
 
    app.UseAuthentication();
    app.UseAuthorization();
    // app.UseSession();
 
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

对中间件管道进行分支

如果请求路径以给定路径开头,则执行分支。

 

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

 

 

参考网址:

https://docs.microsoft.com/zh-cn/dotnet/api/microsoft.aspnetcore.builder?view=aspnetcore-3.1

http://www.zyiz.net/tutorial/detail-4543.html

 

 

相关文章: