ASP.NET MVC:忽略基本控制器类中的自定义属性

Meg*_*att 4 asp.net-mvc inheritance custom-attributes base-class

我的项目中有许多控制器,它们都是从一个名为BaseController的控制器继承的.我编写了一个自定义属性,我将其应用于整个BaseController类,因此每次操作都在我的任何控制器中运行时,该属性将首先运行.

问题是我有几个控制器动作,我想忽略该属性,但我不知道该怎么做.

有人可以帮忙吗?我正在使用MVC 1.

谢谢.

Joh*_*ika 12

在您的自定义属性中,您可以像这样添加此ShouldRun()检查:

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (ShouldRun(filterContext))
        {
            // proceed with your code
        }
    }

    private bool ShouldRun(ActionExecutingContext filterContext)
    {
        var ignoreAttributes = filterContext.ActionDescriptor.GetCustomAttributes(typeof(IgnoreMyCustomAttribute), false);
        if (ignoreAttributes.Length > 0)
            return false;

        return true;
    }
Run Code Online (Sandbox Code Playgroud)

ShouldRun()只是检查你的动作是否有"IgnoreMyCustomAttribute".如果它在那里,那么你的自定义属性将不会做任何事情.

您现在想要创建一个简单的IgnoreMyCustomAttribute,它不执行任何操作:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class IgnoreMyCustomAttribute: ActionFilterAttribute
{
}
Run Code Online (Sandbox Code Playgroud)

每当您使用[IgnoreMyCustom]装饰控制器操作时,MyCustomAttribute都不会执行任何操作.例如:

[IgnoreMyCustom]
public ViewResult MyAction() {
}
Run Code Online (Sandbox Code Playgroud)


Fun*_*nka 10

我对类似的东西有类似的需求,并发现通过创建一个授权过滤器(实现/派生FilterAttribute, IAuthorizationFilter)而不是一个常规动作过滤器(派生自ActionFilterAttribute),并设置Inherited=trueAllowMultiple=false在属性上,它只会在适当的时候运行一次点.

这意味着我能够将我的过滤器从基本控制器(站点范围的默认值)"下载"到派生控制器(例如AdminController或其他),或者甚至更进一步到单个操作方法.

例如,

[AttributeUsage(AttributeTargets.Class|AttributeTargets.Method, Inherited=true, AllowMultiple=false)]
public class MyCustomAttribute : FilterAttribute, IAuthorizationFilter
{
    private MyCustomMode _Mode;
    public MyCustomAttribute(MyCustomMode mode)
    {
        _Mode = mode;
    }
    public virtual void OnAuthorization(AuthorizationContext filterContext)
    {
        if (filterContext == null)
        {
            throw new ArgumentNullException("filterContext");
        }
        // run my own logic here.
        // set the filterContext.Result to anything non-null (such as
        // a RedirectResult?) to skip the action method's execution.
        //
        //
    }
}

public enum MyCustomMode
{
    Enforce,
    Ignore
}
Run Code Online (Sandbox Code Playgroud)

然后使用它,我可以将它应用到我的超级控制器,

[MyCustomAttribute(Ignore)]
public class BaseController : Controller
{
}
Run Code Online (Sandbox Code Playgroud)

我可以为特定控制器更改/覆盖它,甚至可以为特定操作更改/覆盖它!

[MyCustomAttribute(Enforce)]
public class AdministrationController : BaseController
{
    public ActionResult Index()
    {
    }

    [MyCustomAttribute(Ignore)] 
    public ActionResult SomeBasicPageSuchAsAHelpDocument()
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

这允许我针对特定情况"关闭"过滤器,同时仍然能够将其作为默认应用于整个控制器或整个应用程序.

祝好运!