关于ASP.NET MVC 3:MVC自定义操作属性

MVC Custom Action Attribute

在测试期间(至少),我们正在记录每个控制器/操作的一些低级信息。所有控制器均来自我们的自定义BaseController,该自定义BaseController覆盖了OnActionExecuting来进行日志记录。

我们在BaseController中具有一个属性,该属性确定是否将发生此日志记录,以便控制器可以重写OnActionExecuting自身,重置标志,然后调用" base.OnActionExecuting "。该标志通常为true,但是例如,对于某些Json请求,我们想将其关闭。

我们希望做的是创建一个自定义的控制器/动作过滤器来处理该问题,如下所示:

1
2
3
[LogPageAccess(false)]
[HttpGet]
Public ActionResult Foobar()

我敢肯定有一种方法可以做到这一点,但是我还无法弄清楚如何创建自定义属性,并让它重置BaseController中的标志。

谢谢...


在我的项目中,我使用以下命令来验证访问控制器:

1
2
3
4
5
    [Capability(UserCapability.FileManagement)]
    public ActionResult FileList(FileListRequestModel request, bool ajax = false)
    {
        //code
    }

这是我的能力等级

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/// <summary>
/// Decorator to MVC class and method to evaluate if a certain capability is enabled
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class CapabilityAttribute : AuthorizeAttribute
{
    #region Class Attributes

    private object _capability = null;

    #endregion

    #region Public Methods

    /// <summary>
    /// Create a new capability attribute
    /// </summary>
    /// <param name="capability">Context Value passed to the validator</param>
    public CapabilityAttribute(object capability)
    {
        this._capability = capability;
    }

    /// <summary>
    /// Check if attribute is enabled
    /// </summary>
    /// <param name="filterContext"></param>
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        if (!Capability.Enabled(this._capability))
        {
            throw new UnauthorizedAccessException();
        }
        else
        {
            base.OnAuthorization(filterContext);
        }
    }

    #endregion
}

您只需要针对您的情况调整此代码,我希望它会变得有用


我试图建立一个简单的例子来说明你的情况,但是后来意识到我无法将实例数据传递给Attribute-所以说如果我将Log标志设置为false ,我不能用它直接操纵基本控制器的属性。

查看此SO帖子。

这是我正在玩的代码(无法编译-无法通过this):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class BaseController : Controller
{
    public bool LogPageRequests { get; set; }
}

public class LogPageAccess : ActionFilterAttribute
{
    public LogPageAccess(BaseController baseController, bool log = true)
    {
        baseController.LogPageRequests = log;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        //Do Whatever
        base.OnActionExecuting(filterContext);
    }
}

public class SomeController : BaseController
{
    [LogPageAccess(this, false)]
    public ActionResult Index()
    {
        return View();
    }
}

也许您可以使用反射来做一些事情,但是由于您似乎无法将实例数据获取到属性中,因此您可能必须按照过去的方式来做。<铅>