ASP.NET ActionFilter
最后修改于 2025 年 4 月 3 日
在本文中,我们将探讨 ASP.NET 8 中的 ActionFilters。ActionFilters 允许您在控制器操作执行之前或之后运行代码。它们对于处理横切关注点非常强大。
ASP.NET 是一个跨平台、高性能的框架,用于构建现代 Web 应用程序。ActionFilters 提供了一种在操作级别实现类似中间件行为的方法。
基本定义
ASP.NET 中的 ActionFilter 是一个实现 IActionFilter 或 IAsyncActionFilter 接口的特性。它会拦截对控制器操作的请求。
ActionFilters 可以在操作运行之前 (OnActionExecuting) 和完成之后 (OnActionExecuted) 执行代码。它们对于日志记录、验证或修改响应非常有用。
ASP.NET 中的过滤器在一个称为过滤器管道的管道中运行。ActionFilters 在授权过滤器之后,但在结果过滤器和异常过滤器之前执行。
ASP.NET ActionFilter 示例
下面的示例演示了如何创建和使用自定义 ActionFilter 来记录请求信息。
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); var app = builder.Build(); app.MapControllers(); app.Run();
这设置了一个基本的 ASP.NET 应用程序,并支持控制器。MapControllers 方法为控制器启用属性路由。
using Microsoft.AspNetCore.Mvc.Filters;
using System.Diagnostics;
public class LogActionFilter : IActionFilter
{
private readonly ILogger<LogActionFilter> _logger;
public LogActionFilter(ILogger<LogActionFilter> logger)
{
_logger = logger;
}
public void OnActionExecuting(ActionExecutingContext context)
{
_logger.LogInformation($"Action {context.ActionDescriptor.DisplayName} " +
$"is executing at {DateTime.UtcNow}");
// You can access action arguments
foreach (var arg in context.ActionArguments)
{
_logger.LogInformation($"Argument: {arg.Key} = {arg.Value}");
}
}
public void OnActionExecuted(ActionExecutedContext context)
{
var elapsed = Stopwatch.GetTimestamp();
_logger.LogInformation($"Action {context.ActionDescriptor.DisplayName} " +
$"completed at {DateTime.UtcNow}");
if (context.Exception != null)
{
_logger.LogError(context.Exception, "Action threw an exception");
}
}
}
这个自定义 ActionFilter 会在操作执行前后记录信息。它演示了如何访问操作参数和处理异常。
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
[ServiceFilter(typeof(LogActionFilter))]
public class ProductsController : ControllerBase
{
private static List<Product> _products = new()
{
new Product(1, "Laptop", 999.99m),
new Product(2, "Mouse", 19.99m),
new Product(3, "Keyboard", 49.99m)
};
[HttpGet]
public IActionResult GetAllProducts()
{
return Ok(_products);
}
[HttpGet("{id}")]
public IActionResult GetProductById(int id)
{
var product = _products.FirstOrDefault(p => p.Id == id);
if (product == null) return NotFound();
return Ok(product);
}
}
public record Product(int Id, string Name, decimal Price);
控制器使用 [ServiceFilter] 特性应用 LogActionFilter。这可以确保依赖注入对过滤器的构造函数有效。
当此控制器中的任何操作运行时,过滤器都会记录执行详细信息。该示例展示了 ActionFilters 如何在不修改操作方法的情况下添加横切行为。
对于全局注册,您可以在 Program.cs 中添加过滤器:builder.Services.AddControllers(options => options.Filters.Add<LogActionFilter>()); 这会将过滤器应用于所有控制器。
来源
在本文中,我们探讨了 ASP.NET 8 中的 ActionFilters。这些强大的组件有助于以清晰且可维护的方式实现横切关注点。