在 ASP.NET Core 中,ActionFilter 是一种强大的工具,允许开发者在控制器 Action 方法执行前后插入自定义逻辑。通过使用 ActionFilter,开发者可以实现诸如日志记录、权限验证、缓存控制等功能,而无需在每个 Action 方法中重复编写相同的代码。本文将详细介绍如何在 ASP.NET Core 中使用 ActionFilter,包括如何创建自定义 ActionFilter、如何全局注册 ActionFilter、以及 ActionFilter 的常见应用场景。
ActionFilter 是 ASP.NET Core 中的一种过滤器(Filter),它允许开发者在控制器 Action 方法执行前后执行自定义逻辑。ActionFilter 继承自 IActionFilter
或 IAsyncActionFilter
接口,并实现 OnActionExecuting
和 OnActionExecuted
方法(对于同步 ActionFilter)或 OnActionExecutionAsync
方法(对于异步 ActionFilter)。
ActionFilter 的主要作用是在控制器 Action 方法执行前后插入自定义逻辑。通过使用 ActionFilter,开发者可以实现以下功能:
ActionFilter 的生命周期与控制器 Action 方法的执行过程密切相关。ActionFilter 的执行顺序如下:
OnActionExecuting
和 OnActionExecuted
方法。要创建同步 ActionFilter,需要实现 IActionFilter
接口,并实现 OnActionExecuting
和 OnActionExecuted
方法。以下是一个简单的同步 ActionFilter 示例:
public class LogActionFilter : IActionFilter { public void OnActionExecuting(ActionExecutingContext context) { // 在 Action 方法执行前记录日志 var controllerName = context.Controller.GetType().Name; var actionName = context.ActionDescriptor.DisplayName; Console.WriteLine($"Executing {actionName} in {controllerName}"); } public void OnActionExecuted(ActionExecutedContext context) { // 在 Action 方法执行后记录日志 var controllerName = context.Controller.GetType().Name; var actionName = context.ActionDescriptor.DisplayName; Console.WriteLine($"Executed {actionName} in {controllerName}"); } }
要创建异步 ActionFilter,需要实现 IAsyncActionFilter
接口,并实现 OnActionExecutionAsync
方法。以下是一个简单的异步 ActionFilter 示例:
public class LogAsyncActionFilter : IAsyncActionFilter { public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { // 在 Action 方法执行前记录日志 var controllerName = context.Controller.GetType().Name; var actionName = context.ActionDescriptor.DisplayName; Console.WriteLine($"Executing {actionName} in {controllerName}"); // 执行 Action 方法 var resultContext = await next(); // 在 Action 方法执行后记录日志 Console.WriteLine($"Executed {actionName} in {controllerName}"); } }
要将 ActionFilter 全局注册到所有控制器和 Action 方法中,可以在 Startup.cs
文件的 ConfigureServices
方法中使用 AddControllers
方法进行注册。以下是一个全局注册 ActionFilter 的示例:
public void ConfigureServices(IServiceCollection services) { services.AddControllers(options => { options.Filters.Add<LogActionFilter>(); }); }
日志记录是 ActionFilter 的常见应用场景之一。通过在 Action 方法执行前后记录日志,开发者可以轻松追踪应用程序的执行流程。以下是一个日志记录 ActionFilter 的示例:
public class LogActionFilter : IActionFilter { private readonly ILogger<LogActionFilter> _logger; public LogActionFilter(ILogger<LogActionFilter> logger) { _logger = logger; } public void OnActionExecuting(ActionExecutingContext context) { var controllerName = context.Controller.GetType().Name; var actionName = context.ActionDescriptor.DisplayName; _logger.LogInformation($"Executing {actionName} in {controllerName}"); } public void OnActionExecuted(ActionExecutedContext context) { var controllerName = context.Controller.GetType().Name; var actionName = context.ActionDescriptor.DisplayName; _logger.LogInformation($"Executed {actionName} in {controllerName}"); } }
权限验证是另一个常见的 ActionFilter 应用场景。通过在 Action 方法执行前验证用户权限,开发者可以确保只有授权用户才能访问特定资源。以下是一个权限验证 ActionFilter 的示例:
public class AuthorizationFilter : IActionFilter { public void OnActionExecuting(ActionExecutingContext context) { var user = context.HttpContext.User; if (!user.Identity.IsAuthenticated) { context.Result = new UnauthorizedResult(); } } public void OnActionExecuted(ActionExecutedContext context) { // 不需要在 Action 方法执行后执行任何操作 } }
缓存控制是 ActionFilter 的另一个常见应用场景。通过在 Action 方法执行前检查缓存,或在 Action 方法执行后更新缓存,开发者可以显著提高应用程序的性能。以下是一个缓存控制 ActionFilter 的示例:
public class CacheControlFilter : IActionFilter { private readonly IMemoryCache _cache; public CacheControlFilter(IMemoryCache cache) { _cache = cache; } public void OnActionExecuting(ActionExecutingContext context) { var cacheKey = context.HttpContext.Request.Path; if (_cache.TryGetValue(cacheKey, out var cachedResult)) { context.Result = new ObjectResult(cachedResult); } } public void OnActionExecuted(ActionExecutedContext context) { var cacheKey = context.HttpContext.Request.Path; if (context.Result is ObjectResult result && result.Value != null) { _cache.Set(cacheKey, result.Value, TimeSpan.FromMinutes(10)); } } }
异常处理是 ActionFilter 的另一个重要应用场景。通过在 Action 方法执行过程中捕获异常并进行处理,开发者可以确保应用程序的稳定性和可靠性。以下是一个异常处理 ActionFilter 的示例:
public class ExceptionHandlingFilter : IActionFilter { private readonly ILogger<ExceptionHandlingFilter> _logger; public ExceptionHandlingFilter(ILogger<ExceptionHandlingFilter> logger) { _logger = logger; } public void OnActionExecuting(ActionExecutingContext context) { // 不需要在 Action 方法执行前执行任何操作 } public void OnActionExecuted(ActionExecutedContext context) { if (context.Exception != null) { _logger.LogError(context.Exception, "An error occurred while executing the action."); context.Result = new ObjectResult("An error occurred.") { StatusCode = StatusCodes.Status500InternalServerError }; context.ExceptionHandled = true; } } }
在 ASP.NET Core 中,ActionFilter 支持依赖注入(Dependency Injection,DI)。通过在 ActionFilter 的构造函数中注入服务,开发者可以在 ActionFilter 中使用这些服务。以下是一个依赖注入的示例:
public class LogActionFilter : IActionFilter { private readonly ILogger<LogActionFilter> _logger; public LogActionFilter(ILogger<LogActionFilter> logger) { _logger = logger; } public void OnActionExecuting(ActionExecutingContext context) { var controllerName = context.Controller.GetType().Name; var actionName = context.ActionDescriptor.DisplayName; _logger.LogInformation($"Executing {actionName} in {controllerName}"); } public void OnActionExecuted(ActionExecutedContext context) { var controllerName = context.Controller.GetType().Name; var actionName = context.ActionDescriptor.DisplayName; _logger.LogInformation($"Executed {actionName} in {controllerName}"); } }
在 ASP.NET Core 中,ActionFilter 的执行顺序可以通过 Order
属性进行控制。Order
属性的值越小,ActionFilter 的执行顺序越靠前。以下是一个控制 ActionFilter 执行顺序的示例:
public class FirstActionFilter : IActionFilter { public void OnActionExecuting(ActionExecutingContext context) { Console.WriteLine("First ActionFilter - OnActionExecuting"); } public void OnActionExecuted(ActionExecutedContext context) { Console.WriteLine("First ActionFilter - OnActionExecuted"); } } public class SecondActionFilter : IActionFilter { public void OnActionExecuting(ActionExecutingContext context) { Console.WriteLine("Second ActionFilter - OnActionExecuting"); } public void OnActionExecuted(ActionExecutedContext context) { Console.WriteLine("Second ActionFilter - OnActionExecuted"); } } public void ConfigureServices(IServiceCollection services) { services.AddControllers(options => { options.Filters.Add<FirstActionFilter>(order: 1); options.Filters.Add<SecondActionFilter>(order: 2); }); }
在使用 ActionFilter 时,开发者需要注意以下几点:
Order
属性进行控制,但应确保 ActionFilter 的执行顺序不会影响应用程序的逻辑。ActionFilter 是 ASP.NET Core 中一种强大的工具,允许开发者在控制器 Action 方法执行前后插入自定义逻辑。通过使用 ActionFilter,开发者可以实现诸如日志记录、权限验证、缓存控制、异常处理等功能,而无需在每个 Action 方法中重复编写相同的代码。本文详细介绍了如何在 ASP.NET Core 中使用 ActionFilter,包括如何创建自定义 ActionFilter、如何全局注册 ActionFilter、以及 ActionFilter 的常见应用场景。希望本文能帮助开发者更好地理解和应用 ActionFilter,从而提高应用程序的开发效率和代码质量。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。