MVC自定义操作属性

时间:2011-09-21 18:59:40

标签: asp.net-mvc-3 attributes controller action

在测试期间(至少)我们会记录每个控制器/操作的一些低级信息。所有控制器都是从我们的自定义BaseController派生的,它会覆盖OnActionExecuting以进行日志记录。

我们在BaseController中有一个属性,用于确定是否会发生此日志记录,以便控制器可以覆盖OnActionExecuting本身,重置标志,然后调用“base.OnActionExecuting”。该标志通常是正确的,但我们想要为某些Json请求关闭它,例如。

我们更喜欢做的是创建一个自定义控制器/动作过滤器来处理它,如下所示:

[LogPageAccess(false)]
[HttpGet]
Public ActionResult Foobar()

我确信有办法实现,但我无法弄清楚如何创建自定义属性并让它重置BaseController中的标志。

...谢谢

2 个答案:

答案 0 :(得分:2)

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

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

这是我的能力等级

/// <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
}

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

答案 1 :(得分:0)

我试图在一段时间内构建一个简单的情况示例,但后来意识到我无法将实例数据传递给Attribute - 所以说如果我设置Log标志到false,我无法使用它直接操纵基本控制器的属性。

Check out this SO post

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

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();
    }
}

也许你可以用反射做一些事情,但可能就是你必须按照你一直这样做的方式去做,因为它似乎无法将实例数据传递给属性。 / p>

相关问题