2011-09-21 96 views
3

在测试期间(至少)我们记录每个控制器/操作的一些底层信息。所有的控制器都来自我们自定义的BaseController,它覆盖了OnActionExecuting来完成日志记录。MVC自定义操作属性

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

我们宁愿做的是创建一个自定义的控制器/动作过滤器来处理,这样的事情:

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

我敢肯定有办法做到这一点,但我没有已经能够弄清楚如何创建自定义属性并让它重置BaseController中的标志。

谢谢...

在项目中,我使用

回答

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 
} 

你只需要适应这个代码为你的情况,我希望它变得有用

+0

需要类似的东西,这让我需要去的地方。但是,我使用'filterContext.Result = new HttpUnauthorizedResult();'而不是抛出'UnauthorizedAccessException',这让我觉得更适合MVC页面。您可以查看[UnauthorizedAccessException]的MSDN文档(http://msdn.microsoft.com/en-us/library/system.unauthorizedaccessexception.aspx)以了解为什么我不觉得它适合这种情况。 –

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

也许你可以做一些反思,但它可能的情况是,你”你必须按照你一直这样做的方式来完成它,因为它似乎不可能获得实例数据到属性。

+0

您可以从上下文中获取控制器。 – SLaks

+0

@SLaks你能给我一个快速和肮脏的例子吗? – davecoulter

+0

'filterContext.Controller' – SLaks