ASP.NET Core 中间件介绍

在这里插入图片描述

ASP.NET Core 引入了许多新概念,开发人员需要学习这些新概念来开发基于 Web 的现代应用程序。其中一个概念是“中间件”,它允许开发人员在 Web 请求和响应处理期间运行一系列组件(又名中间件)。在本教程中,我将概述 ASP.NET Core 中间件。我们还将学习如何使用 ASP.NET Core 中提供的一些内置中间件构建请求/响应管道。

什么是中间件?

中间件是处理传入请求和传出响应的组件或一段代码。这些组件以这样的方式链接在一起,管道中的每个组件都有机会在将请求传递给管道中的下一个中间件之前运行一些逻辑或处理请求。每个中间件也有机会以相反的顺序处理传出的响应。
在这里插入图片描述

配置中间件管道

我们通常使用 IApplicationBuilder 类在 Startup.cs 文件的 Configure 方法中配置 ASP.NET 中间件,该类的实例可用作 Configure 方法中的参数。

public class Startup
{
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        // Configure Middleware Pipeline Here
    }
}

要构建请求管道,我们需要将名为 RequestDelegate 的内置 ASP.NET Core 委托的多个实例链接在一起。 RequestDelegate 表示任何接受 HttpContext 作为参数并返回 Task 的方法。每个委托都可以在下一个委托之前和之后执行操作。

public delegate System.Threading.Tasks.Task RequestDelegate(HttpContext context);

我们可以在 IApplicationBuilder 类上使用 RunMapUse 扩展方法以两种不同的方式配置 RequestDelegates

  1. 我们可以将中间件内联配置为匿名方法。这种类型的中间件称为内联中间件。
  2. 我们还可以创建一个可重用的 C# 类并将该类配置为中间件。

下面给出了一个简单的内联中间件示例,其中我们使用 Run 扩展方法来配置单个请求委托来处理所有传入请求。以下匿名函数将被调用以响应每个 HTTP 请求。

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

上面示例中使用的 Run 方法没有接收 next 参数,这意味着它无法调用管道中的下一个中间件。当我们想要终止管道并且没有其他中间件要执行时,我们通常在管道的末尾使用 Run() 方法。要按顺序配置多个中间件组件,我们可以使用 Use() 扩展方法,如下例所示。

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.Use(async (context, next) =>
        {
            if (context.Request.Path == "/hello")
            {
                await context.Response.WriteAsync("Hello World!");
            }
 
            await next();
        });
 
        app.Run(async context =>
        {
            await context.Response.WriteAsync("End of Middleware Pipeline.");
        });    
    }
}

如果请求 URL 不以 /hello 结尾,那么我们的第一个中间件代码将不会执行,请求将移动到下一个中间件,该中间件将文本“中间件管道结束”写入响应。
在这里插入图片描述
如果请求 URL 以 /hello 结尾,那么我们的第一个中间件代码将执行并写入“Hello World!”到响应,然后请求将移动到下一个中间件,该中间件将文本“中间件管道结束”写入响应。 在这里插入图片描述

中间件处理顺序

从上面的简单示例中可以清楚地看出,配置中间件的顺序很重要。例如,我们可以轻松地对下面示例中的 First 和 Second 中间件重新排序,并可以以不同的顺序执行代码。

app.Use(async (context, next) =>
{
    await context.Response.WriteAsync("First");
    await next();
});
 
app.Use(async (context, next) =>
{
    await context.Response.WriteAsync("Second");
    await next();
});            
 
app.Run(async context =>
{
    await context.Response.WriteAsync("Last.");
});

下图显示了配置 ASP.NET Core 内置中间件管道以处理请求和响应的典型顺序。它还显示了我们可以在哪里添加自定义中间件来运行我们的自定义逻辑。在这里插入图片描述
在实际应用程序中,不建议在 Startup.cs 文件中内联定义所有中间件组件。我们可以创建单独的 C# 类并在这些类中将我们的自定义中间件定义为扩展方法。下面的示例展示了如何在单独的 C# 类中将自定义中间件定义为扩展方法。

public static class ApplicationBuilderExtensions
{
    public static void UseFirstMiddleware(this IApplicationBuilder app)
    {
        app.Use(async (context, next) =>
        {
            await context.Response.WriteAsync("First");
            await next();
        });
    }
 
    public static void UseSecondMiddleware(this IApplicationBuilder app)
    {
        app.Use(async (context, next) =>
        {
            await context.Response.WriteAsync("Second");
            await next();
        });
    }
 
    public static void UseLastMiddleware(this IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Last");
        });
    }
}

一旦定义了上述中间件,就可以在Startup.cs文件的Configure方法中调用它们,如下所示。

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseFirstMiddleware();
    app.UseSecondMiddleware();
    app.UseLastMiddleware();
}

使用 ASP.NET Core 内置中间件

ASP.NET Core 是一个模块化框架,这意味着您可以按需添加/删除功能和中间件。 ASP.NET Core 提供了一些内置中间件,还有更多可以通过 Nuget 包管理器添加为第三方库。一些最常见的中间件有AuthenticationAuthorizationMVCSessionStatic Files等,大多数时候只需要调用对应的UseXXX方法来配置内置甚至第三方的中间件。例如,如果您想向网站访问者显示欢迎页面,您可以如下配置 WelcomePageMiddleware

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseWelcomePage();
}

如果您将在浏览器中运行您的项目,您将看到以下欢迎页面。在这里插入图片描述
上面的中间件是 Microsoft ASP.NET Core 诊断包的一部分,其中还包含一些其他有用的中间件。例如,您可以使用以下两个中间件在开发和生产环境中配置和显示不同的错误页面。

if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Home/Error");
}

同样,有内置的中间件来配置路由和静态文件,例如项目中的样式表、JavaScript、图像等。

app.UseStaticFiles();
app.UseRouting();

如果要检查应用程序的健康状况,可以注册健康检查服务,然后配置端点以查看应用程序健康状况,如下所示:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddHealthChecks();
}
 
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseRouting();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHealthChecks("/health");
    });
}

如果您将在浏览器中运行该应用程序并在 URL 末尾键入 /heath,您将能够看到“健康”消息,表明您的应用程序处于良好状态。在这里插入图片描述
显然,我无法在本教程中涵盖所有内置中间件,因此如果您有兴趣了解有关这些中间件的更多信息,可以转到 Microsoft 官方文档

总结概括

在本教程中,介绍了 ASP.NET Core 中间件的基础知识,向您展示如何编写代码来处理传入请求和传出响应。虽然我在本教程中编写了非常基本的中间件组件,但您可以使用相同的概念在您的应用程序中编写更复杂的中间件。

posted @ 2021-07-22 19:26  cool2feel  阅读(398)  评论(0编辑  收藏  举报