You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 12:30:43