在测试期间(至少)我们会记录每个控制器/操作的一些低级信息。所有控制器都是从我们的自定义BaseController派生的,它会覆盖OnActionExecuting以进行日志记录。
我们在BaseController中有一个属性,用于确定是否会发生此日志记录,以便控制器可以覆盖OnActionExecuting本身,重置标志,然后调用“base.OnActionExecuting”。该标志通常是正确的,但我们想要为某些Json请求关闭它,例如。
我们更喜欢做的是创建一个自定义控制器/动作过滤器来处理它,如下所示:
[LogPageAccess(false)]
[HttpGet]
Public ActionResult Foobar()
我确信有办法实现,但我无法弄清楚如何创建自定义属性并让它重置BaseController中的标志。
...谢谢
答案 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
,我无法使用它直接操纵基本控制器的属性。
以下是我正在玩的代码(不编译 - 无法通过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>