如何在 class 级别验证已在 MVC 中声明时使用操作级别验证覆盖自定义过滤器属性

how to override a custom filter attribute with action level validation while the class level validation is already declared in MVC

我的控制器正在使用 class 级别的属性,它只允许一个角色访问。这个控制器有 20 多个动作。但是对于一个动作,我需要一个角色才能获得访问权限。我已经在 class 级别声明了属性过滤器,因此它可以很好地处理控制器 class 中的所有操作。但是现在我只想在同一个控制器中为一个动作覆盖这个。有没有可能?我正在使用 .Net 4.5 版。

过滤器属性实现如下:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class RequireModulePermissionAttribute : AuthorizeAttribute
{
   //code goes here
}

控制器class:

[RequireModulePermission("Admin")]
public class AdministrationController : Controller
{
    [HttpPost]
    [RequireModulePermission("Admin","Supervisor")]
    public ActionResult CreateUser(UserViewModel userVM)
    {
       //code goes here
    }   
}

看看这个答案(看案例2)

基本上您需要第二个属性来表示覆盖。

所以你的属性变成:

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
    public class RequireModulePermissionAttribute : AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            var action = filterContext.ActionDescriptor;
            if (action.IsDefined(typeof(OverrideRequireModulePermissionAttribute ), true)) return;
            //code goes here
        }
    }

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
    public class OverrideRequireModulePermissionAttribute : AuthorizeAttribute
    {
       public override void OnAuthorization(AuthorizationContext filterContext)
       {
           base.OnAuthorization(filterContext);
       }
    } 

你喜欢用它

[RequireModulePermission("Admin")]
public class AdministrationController : Controller
{
    [HttpPost]
    [OverrideRequireModulePermission("Admin","Supervisor")]
    public ActionResult CreateUser(UserViewModel userVM)
    {
       //code goes here
    }   
}

还有一个替代方法,您可以实际设置 AllowMultiple = false。

这样只有1个filter会生效,按照filter的执行顺序:Global -> Controller -> Action。