ASP.NET Core中的Middleware(中间件)是一种可以装配到应用处理管道中的组件,它用于拦截请求和响应并进行进一步处理。ASP.NET Core中大量的内置功能都是通过中间件实现的,比如身份验证、授权、CORS限制等,实际开发中我们也可以自定义中间件实现我们自己的业务逻辑。
自定义中间件最简单的方式是使用Lambda函数,我们直接在WebApplication
对象上调用Use()
方法并向其中传入我们自定义的中间件逻辑。
app.Use(async (context, next) =>
{
Console.WriteLine($"收到请求 {context.Request.GetDisplayUrl()}");
await next();
Console.WriteLine("请求处理完成");
});
代码中,Use()
方法用于将一个中间件添加到请求管道中,async (context, next) => {}
实际上是一个Lambda表达式写法的异步委托,其中context
是HttpContext
对象,包含了请求的所有信息(如请求头、请求路径、查询字符串等)。next
是一个表示调用管道中下一个中间件的异步方法,在当前中间件中调用await next()
,会将请求传递给下一个中间件,而在调用下一个中间件之前和之后,就是我们自定义的中间件处理逻辑了。
如果中间件代码比较复杂,也可以将其抽取到单独的类中,下面是一个例子。
using Microsoft.AspNetCore.Http.Extensions;
namespace DemoWebAPI.Middlewares;
public class MyLogMiddleware
{
private RequestDelegate _next;
public MyLogMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
Console.WriteLine($"收到请求 {context.Request.GetDisplayUrl()}");
await _next(context);
Console.WriteLine("请求处理完成");
}
}
public static class MyLogMiddlewareExtensions
{
public static IApplicationBuilder UseMyLog(this IApplicationBuilder builer)
{
return builer.UseMiddleware<MyLogMiddleware>();
}
}
中间件类需要满足几个要求,它的构造函数要传入RequestDelegate
委托,此外还要对外暴露一个InvokeAsync()
方法,我们在该方法中编写具体的中间件逻辑。这里我们还对IApplicationBuilder
添加了一个方法扩展UseMyLog()
方便注册我们的自定义中间件,我们可以在Program.cs
中使用如下写法注册中间件。
app.UseMyLog();
中间件的执行顺序是根据它们在管道中注册的顺序来决定的。请求时中间件按注册顺序依次执行,响应时中间件按照逆序执行。下面例子中我们在代码里依次注册两个中间件,每个中间件都会在请求处理的前后打印一条信息。
app.Use(async (context, next) =>
{
Console.WriteLine($"中间件1:收到请求 {context.Request.GetDisplayUrl()}");
await next();
Console.WriteLine("中间件1:请求处理完成");
});
app.Use(async (context, next) =>
{
Console.WriteLine($"中间件2:收到请求 {context.Request.GetDisplayUrl()}");
await next();
Console.WriteLine("中间件2:请求处理完成");
});
当完成一个请求时,我们可以看到输出了类似如下的内容。
中间件1:收到请求 http://localhost:5062/api/Demo/DemoAction
中间件2:收到请求 http://localhost:5062/api/Demo/DemoAction
中间件2:请求处理完成
中间件1:请求处理完成
之前路由系统章节我们介绍过,ASP.Net Core的路由注册和分发是通过中间件实现的,除此之外,ASP.Net Core还有内多内置中间件功能,下面表格列出了一些常用的中间件。
中间件类型 | Use方法示例 | 说明 |
---|---|---|
Authorization | app.UseAuthorization() |
启用授权中间件,确保请求的用户具有必要的权限来访问资源。 |
Authentication | app.UseAuthentication() |
启用身份验证中间件,用于验证请求中的用户身份。 |
StaticFiles | app.UseStaticFiles() |
启用静态文件服务器,将文件直接从服务器提供给客户端,如图片、CSS、JavaScript等。 |
Session | app.UseSession() |
启用会话中间件,用于存储和读取HTTP请求之间共享的会话状态。 |
CORS | app.UseCors() |
启用跨源资源共享(CORS)中间件,允许来自不同源的客户端访问API。 |
HTTPSRedirection | app.UseHttpsRedirection() |
启用HTTPS重定向中间件,将所有HTTP请求重定向到HTTPS。 |
ExceptionHandler | app.UseExceptionHandler("/Home/Error") |
启用全局异常处理,中间件将捕获并处理未处理的异常,通常用于生产环境中的错误页面。 |
DeveloperExceptionPage | app.UseDeveloperExceptionPage() |
启用开发人员异常页面,在开发环境中显示详细的错误信息和堆栈追踪。 |
RequestLocalization | app.UseRequestLocalization() |
启用请求本地化中间件,基于请求头的语言设置来响应不同语言的内容。 |
HealthChecks | app.UseHealthChecks("/health") |
启用健康检查中间件,用于检查应用程序或服务的健康状态,并在指定的端点提供响应。 |
实际开发中,我们如果要实现一个功能,最好先查看ASP.Net Core本身是否已经提供了类似的中间件,这样能省去重复“造轮子”的麻烦。有关这些中间件的使用,我们会在后续章节涉及相关功能时逐步介绍。