在 ASP.NET Core 中,中间件(Middleware) 和 过滤器(Filter) 都可以在请求处理过程中执行逻辑,但它们的作用范围、执行阶段和使用场景有所不同。
1. 中间件(Middleware)
概念
- 中间件 是 ASP.NET Core 请求处理管道的一部分,每个中间件可以:
- 处理请求(完全拦截请求并生成响应)。
- 修改请求 并将其传递给下一个中间件。
- 处理响应(在响应返回前修改它)。
特点
- 全局作用:应用程序级别的请求处理组件,作用于所有请求。
- 管道式执行:按注册顺序依次执行(洋葱模型)。
- 适用于全局逻辑:如日志记录、异常处理、身份验证、跨域请求(CORS)、静态文件处理等。
执行流程
- 请求进入 第一个中间件。
- 依次经过 每个中间件,直到到达终点(如 MVC 控制器)。
- 响应返回时 依次经过所有中间件的“响应处理”部分。
示例
在 Program.cs
(ASP.NET Core 6+)中注册中间件:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// 记录请求日志的中间件
app.Use(async (context, next) =>
{
Console.WriteLine($"Request: {context.Request.Path}");
await next(); // 调用下一个中间件
Console.WriteLine($"Response: {context.Response.StatusCode}");
});
// 终结请求的中间件(Hello World)
app.Run(async context =>
{
await context.Response.WriteAsync("Hello, World!");
});
app.Run();
常见中间件
- 身份验证(Authentication):
app.UseAuthentication()
- 授权(Authorization):
app.UseAuthorization()
- 异常处理(Exception Handling):
app.UseExceptionHandler()
- 静态文件(Static Files):
app.UseStaticFiles()
- 跨域(CORS):
app.UseCors()
2. 过滤器(Filter)
概念
- 过滤器 是 ASP.NET Core MVC 或 API 框架中的一部分,专用于控制器和动作方法,用于拦截请求和响应,执行特定逻辑,如授权、日志、异常处理等。
特点
- 局部作用:作用于特定的控制器或方法,不像中间件那样全局生效。
- 按类型分类:
- 授权过滤器(Authorization Filters):
IAuthorizationFilter
(如[Authorize]
)。 - 资源过滤器(Resource Filters):
IResourceFilter
(请求前后处理,如缓存)。 - 操作过滤器(Action Filters):
IActionFilter
(请求前后处理,如日志)。 - 异常过滤器(Exception Filters):
IExceptionFilter
(异常处理)。 - 结果过滤器(Result Filters):
IResultFilter
(返回结果前处理,如包装格式)。
- 授权过滤器(Authorization Filters):
执行流程
- 授权过滤器 先执行,决定是否允许访问。
- 资源过滤器 在动作方法之前执行,可以提前返回结果(如缓存)。
- 操作过滤器 在控制器方法执行前后执行(如日志记录)。
- 异常过滤器 处理控制器方法中的异常。
- 结果过滤器 处理返回的结果(如格式化数据)。
示例
创建一个自定义 Action 过滤器
public class LogActionFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
Console.WriteLine($"Executing: {context.ActionDescriptor.DisplayName}");
}
public void OnActionExecuted(ActionExecutedContext context)
{
Console.WriteLine($"Executed: {context.ActionDescriptor.DisplayName}");
}
}
在控制器或方法上应用
[ServiceFilter(typeof(LogActionFilter))]
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
}
常见过滤器
- 身份验证:
[Authorize]
- 异常处理:
[HandleError]
- 日志:
IActionFilter
- 缓存:
[ResponseCache(Duration = 60)]
3. 对比总结
特性 | 中间件(Middleware) | 过滤器(Filter) |
---|---|---|
作用范围 | 整个应用,影响所有请求 | MVC / API 级别,作用于特定控制器或方法 |
执行阶段 | 在 请求管道 处理过程中执行 | 在 MVC 执行生命周期 内部执行 |
适用场景 | 全局:日志、异常、身份验证、CORS、静态文件 | 局部:日志、身份验证、数据格式化、缓存 |
可拦截的对象 | 整个 HTTP 请求 | MVC 控制器、方法的执行 |
执行顺序 | 按照 管道顺序 执行 | 不同类型的过滤器 按顺序执行 |
是否影响所有请求 | 是(全局生效) | 否(仅限 MVC/API) |
是否能终结请求 | 可以(例如 app.Run ) | 不可以(只能影响 MVC 控制器) |
实现方式 | app.UseMiddleware<T>() | [Authorize] , IActionFilter , IExceptionFilter |
4. 什么时候用中间件?什么时候用过滤器?
✅ 使用中间件
- 需要全局应用的功能,比如:
- 日志记录
- 认证(JWT、OAuth)
- CORS(跨域)
- 全局异常处理
- 访问计数
- 处理静态文件
✅ 使用过滤器
- 需要针对某些 API/控制器方法执行的功能,比如:
- 记录某个 API 方法的访问日志
- 只对某个控制器做身份验证
- 统一格式化 API 返回结果
- 处理某个控制器级别的异常
5. 组合使用中间件和过滤器
中间件和过滤器可以配合使用,例如:
-
身份验证:
- 在 中间件(
app.UseAuthentication()
)中执行JWT 验证。 - 在 过滤器(
[Authorize]
)中执行权限检查。
- 在 中间件(
-
日志记录:
- 在 中间件 记录所有请求的访问路径。
- 在 过滤器 记录某些关键 API 的调用情况。
6. 结论
- 中间件 适用于整个应用的全局功能,如日志、身份验证、异常处理、静态文件等。
- 过滤器 适用于MVC 或 API 的特定控制器或方法,如授权、缓存、格式化等。
- 它们可以配合使用,中间件可以处理全局逻辑,过滤器处理特定控制器逻辑,提升 ASP.NET Core 应用的可维护性和扩展性。