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。这些强大的组件有助于以清晰且可维护的方式实现横切关注点。