控制器和动作的MVC属性

Dav*_*vid 7 c# asp.net-mvc

有没有办法在Controller级别添加属性,但不能在特定操作上添加.例如,如果我在我的控制器中有10个动作,那些动作中只有一个不需要我创建的特定属性.

[MyAttribute]
public class MyController : Controller
{
    public ActionResult Action1() {}
    public ActionResult Action2() {}

    [Remove_MyAttribute]
    public ActionResult Action3() {}
}

我可能会将此Action移动到另一个控制器(但不喜欢)或者我可以将MyAttribute应用于除Action3之外的所有操作,但只是想如果有更简单的方法?

Fun*_*nka 7

我知道我的回答还差一点(将近四年),但是我遇到了这个问题,想分享一个我设计的解决方案,该方案可以让我做最初问题想做的事情,以防万一。将来还有其他人。

该解决方案涉及一个名为的小宝石AttributeUsage,它使我们可以在控制器(甚至任何基本控制器!)上指定属性,然后根据需要在单个操作或子控制器上重写(忽略/删除)。它们将“级联”到只有最细粒度的属性实际触发的位置:即,它们从最不特定的(基本控制器)到更特定的(派生的控制器)再到最特定的(动作方法)。

这是如何做:

[AttributeUsage(AttributeTargets.Class|AttributeTargets.Method, Inherited=true, AllowMultiple=false)]
public class MyCustomFilterAttribute : ActionFilterAttribute
{

    private MyCustomFilterMode _Mode = MyCustomFilterMode.Respect;        // this is the default, so don't always have to specify

    public MyCustomFilterAttribute()
    {
    }
    public MyCustomFilterAttribute(MyCustomFilterMode mode)
    {
        _Mode = mode;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (_Mode == MyCustomFilterMode.Ignore)
        {
            return;
        }

        // Otherwise, respect the attribute and work your magic here!
        //
        //
        //
    }

}

public enum MyCustomFilterMode
{
    Ignore = 0,
    Respect = 1
}
Run Code Online (Sandbox Code Playgroud)

(我听说您喜欢属性,所以我在属性上添加了一些属性!这就是使魔术在最顶层起作用的真正原因:允许它们继承/层叠,但仅允许其中一个执行。)

现在的用法如下:

[MyCustomFilter]
public class MyBaseController : Controller
{
    // I am the application's base controller with the filter,
    // so any derived controllers will ALSO get the filter (unless they override/Ignore)
}

public class HomeController : MyBaseController
{
    // Since I derive from MyBaseController,
    // all of my action methods will also get the filter,
    // unless they specify otherwise!

    public ActionResult FilteredAction1...
    public ActionResult FilteredAction2...

    [MyCustomFilter(Ignore)]
    public ActionResult MyIgnoredAction...    // I am ignoring the filter!

}

[MyCustomFilter(Ignore)]
public class SomeSpecialCaseController : MyBaseController
{
    // Even though I also derive from MyBaseController, I can choose
    // to "opt out" and indicate for everything to be ignored

    public ActionResult IgnoredAction1...
    public ActionResult IgnoredAction2...

    // Whoops! I guess I do need the filter on just one little method here:
    [MyCustomFilter]
    public ActionResult FilteredAction1...

}
Run Code Online (Sandbox Code Playgroud)

我希望可以进行编译,我从一些类似的代码中将其删除,并对其进行了一些搜索和替换,因此它可能并不完美。


Dav*_*vid 3

约翰内斯给出了正确的解决方案,这就是我的编码方式......希望它对其他人有帮助。

[我的过滤器(“我的操作”)]
公共类 HomeController :控制器
{
    公共操作结果操作1...
    公共 ActionResult Action2...
    公共 ActionResult 我的操作...
}

公共类压缩过滤器:ActionFilterAttribute
{
    私有 IList _ExcludeActions = null;

    公共压缩过滤器()
    {
        _ExcludeActions = 新列表();
    }

    公共压缩过滤器(字符串排除动作)
    {
        _ExcludeActions = new List(excludeActions.Split(','));
    }

    公共覆盖无效OnActionExecuting(ActionExecutingContext filterContext)
    {
        HttpRequestBase 请求 = filterContext.HttpContext.Request;

        字符串 currentActionName = (string)filterContext.RouteData.Values["action"];

        if (_ExcludeActions.Contains(currentActionName))
            返回;

        ...
    }