.NET Core 6.0中ServiceFilter调用自定义过滤器未触发问题排查
自定义带构造函数依赖注入的ActionFilter未触发问题排查
问题概述
实现带构造函数依赖注入的自定义ActionFilter时,已按官方教程配置ServiceFilter特性并在DI容器中注册过滤器,但过滤器逻辑始终未执行。
相关代码
CustomFilter.cs
public class CustomFilter : IActionFilter { private readonly UserManager<Kullanici> _userManager; public CustomFilter(UserManager<Kullanici> userManager) { _userManager = userManager; } public void OnActionExecuted(ActionExecutedContext context) { var user = _userManager.GetUserAsync(context.HttpContext.User).Result; if (user.KullaniciTipi != Models.Enums.KullaniciTipi.Mezun) { var controller = context.Controller as Controller; controller.TempData["ErrorMessage"] = "Erişim hakkınız bulunmamaktadır."; context.HttpContext.Response.Redirect("/"); } } public void OnActionExecuting(ActionExecutingContext context) { } }
控制器Action
[ServiceFilter(typeof(CustomFilter))] public async Task<IActionResult> Profil() { var user = await _userManager.GetUserAsync(HttpContext.User); var mezunHesabi = user.MezunHesabi; ProfilViewModel profilViewModel = new ProfilViewModel(); profilViewModel.MapFromModel(mezunHesabi); return View(profilViewModel); }
Program.cs注册代码
builder.Services.AddScoped<CustomFilter>();
问题根源与修复方案
1. 逻辑放错了过滤器生命周期方法
你把权限校验逻辑写在了OnActionExecuted方法中,这个方法是动作执行完成后才触发的,而拦截未授权访问的需求应该在动作执行前处理,需要把逻辑移到OnActionExecuting方法中。
2. 异步方法同步调用存在死锁风险
直接用.Result调用异步方法GetUserAsync可能引发死锁,建议改为实现IAsyncActionFilter接口,用异步方式处理:
public class CustomFilter : IAsyncActionFilter { private readonly UserManager<Kullanici> _userManager; public CustomFilter(UserManager<Kullanici> userManager) { _userManager = userManager; } public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { var user = await _userManager.GetUserAsync(context.HttpContext.User); if (user?.KullaniciTipi != Models.Enums.KullaniciTipi.Mezun) { var controller = context.Controller as Controller; controller.TempData["ErrorMessage"] = "Erişim hakkınız bulunmamaktadır."; // 通过设置Result终止后续流程,而非直接操作Response context.Result = new RedirectResult("/"); return; } // 允许执行后续动作 await next(); } }
3. 正确终止请求流程
不要直接调用context.HttpContext.Response.Redirect,应该设置context.Result为RedirectResult,让ASP.NET Core框架正确处理请求终止,避免后续动作继续执行。
4. 确认控制器服务注册
确保Program.cs中已注册控制器与视图服务:
builder.Services.AddControllersWithViews();
验证
修改完成后,非Mezun类型用户访问Profil动作时,会在动作执行前被拦截,自动跳转到首页并显示错误提示,过滤器逻辑即可正常触发。
内容的提问来源于stack exchange,提问作者ısmaıl sahan
相关产品推荐
相关产品推荐

