ASP.NET Core 中间件
ASP.NET Core 引入了一个叫做中间件的新概念。中间件只是一个组件(类),它在 ASP.NET Core 应用程序中的每个请求上执行。在经典的 ASP.NET 中,HttpHandlers 和 HttpModules 是请求管道的一部分。中间件类似于 HttpHandlers 和 HttpModules,两者都需要在每个请求中配置和执行。
通常,ASP.NET Core web 应用程序中会有多个中间件。它可以是通过 NuGet 添加的框架提供的中间件,也可以是您自己的定制中间件。我们可以在请求管道中设置中间件执行的顺序。每个中间件都添加或修改 http 请求,并可选地将控制权传递给下一个中间件组件。下图说明了中间件组件的执行。

中间件构建请求管道。下图说明了 ASP.NET Core 请求处理。

配置中间件
我们可以使用 IApplicationBuilder 实例在 Startup 类的 configure 方法中配置中间件。下面的实例使用 Run 方法添加了一个中间件,该方法根据每个请求返回字符串 "HelloWorld!"
public class Startup{public Startup(){}public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory){//使用 IApplicationBuilder 在这里配置中间件..app.Run(async (context) =>{await context.Response.WriteAsync("Hello World!");});// other code removed for clarity..}}
了解 Run 方法
我们使用 Run 扩展方法添加中间件。以下是 Run 方法的签名:
public static void Run(this IApplicationBuilder app, RequestDelegate handler)
Run 方法是 IApplicationBuilder 上的一个扩展方法,并接受 RequestDelegate 参数。RequestDelegate 是处理请求的委托方法。以下是 RequestDelegate 签名。
public delegate Task RequestDelegate(HttpContext context);
如上所述,Run 方法接受一个方法作为参数,其签名应与 RequestDelegate 匹配。因此,该方法应接受 HttpContext 参数并返回 Task。因此,您可以在 Run 方法中指定 lambda 表达式或指定函数。上面 Run 方法中指定的 lambda 表达式与下面示例中的表达式类似。
public class Startup{public Startup(){}public void Configure(IApplicationBuilder app, IHostingEnvironment env){app.Run(MyMiddleware);}private Task MyMiddleware(HttpContext context){return context.Response.WriteAsync("Hello World! ");}}
上面的 MyMiddleware 函数不是异步的,因此将阻塞线程直到它完成执行。因此,通过使用异步和等待来提高性能和可伸缩性,使其成为异步的。
// 为清晰起见,删除了其他代码public void Configure(IApplicationBuilder app, IHostingEnvironment env){app.Run(MyMiddleware);}private async Task MyMiddleware(HttpContext context){await context.Response.WriteAsync("Hello World! ");}
因此,上面的代码片段与下面的代码片段相同。
app.Run(async context => await context.Response.WriteAsync("Hello World!") );app.Run(async (context) =>{await context.Response.WriteAsync("Hello World!");});
因此,通过这种方式,我们可以使用 Run 方法配置中间件。
配置多个中间件
大多数情况下,ASP.NET Core 应用程序中将有多个中间件组件,这些组件将按顺序执行。Run 方法添加了一个终端中间件,因此它不能调用下一个中间件,因为它将是序列中的最后一个中间件。以下命令将始终执行第一个 Run 方法,并且永远不会到达第二个 Run 方法。
public void Configure(IApplicationBuilder app, IHostingEnvironment env){app.Run(async (context) =>{await context.Response.WriteAsync("Hello World From 1st Middleware");});// the following will never be executedapp.Run(async (context) =>{await context.Response.WriteAsync("Hello World From 2nd Middleware");});}
要配置多个中间件,请使用 use() 扩展方法。它类似于 Run() 方法,只是它包含下一个参数来调用序列中的下一个中间件。考虑以下实例。
public void Configure(IApplicationBuilder app, IHostingEnvironment env){app.Use(async (context, next) =>{await context.Response.WriteAsync("Hello World From 1st Middleware!");await next();});app.Run(async (context) =>{await context.Response.WriteAsync("Hello World From 2nd Middleware");});}
上面的实例将在浏览器中显示 Hello World From 1st Middleware!来自第二中间件的 Hello World!。
因此,我们可以使用 use() 方法按我们喜欢的顺序配置多个中间件。
通过 NuGet 添加内置中间件
ASP.NET Core 是一个模块化框架。通过 NuGet 安装不同的插件,我们可以在应用程序中添加所需的服务器端功能。有许多中间件插件可用于我们的应用程序。
以下是一些内置中间件:
| 中间件 | 描述 |
|---|---|
| Authentication | 添加身份验证支持。 |
| CORS | 配置跨源资源共享。 |
| Routing | 为 MVC 或 web 表单添加路由功能 |
| Session | 添加对用户会话的支持。 |
| StaticFiles | 添加对服务静态文件和目录浏览的支持。 |
| Diagnostics | 添加对报告和处理异常和错误的支持。 |
Diagnostics 中间件
让我们安装并使用 Diagnostics 中间件。Diagnostics 诊断中间件用于报告和处理 ASP.NET Core 中的异常和错误,并诊断 Entity Framework Core 迁移错误。
打开项目,添加 Microsoft.AspNetCore.Diagnostics 依赖项。等待一段时间,直到 Visual Studio 恢复包。
该软件包包括以下中间件及其扩展方法。
| 中间件 | 扩展方法 | 描述 |
|---|---|---|
| DeveloperExceptionPageMiddleware | UseDeveloperExceptionPage() | 从管道中捕获同步和异步异常,并生成 HTML 错误响应。 |
| ExceptionHandlerMiddleware | UseExceptionHandler() | 捕获异常,记录它们并在备用管道中重新执行。 |
| StatusCodePagesMiddleware | UseStatusCodePages() | 检查状态代码在 400 和 599 之间的响应。 |
| WelcomePageMiddleware | UseWelcomePage() | 显示根路径的欢迎页面。 |
我们可以调用各自的 Use* 扩展方法来在 Startup 类的 configure 方法中使用上述中间件。
让我们添加 welcomePage 中间件,它将显示根路径的欢迎页面。
public void Configure(IApplicationBuilder app, IHostingEnvironment env){app.UseWelcomePage();//other code removed for clarity}
这样,我们可以使用不同的 use* 扩展方法来包含不同的中间件。