我有一个BaseController,它有一个属性而不是单独的动作,因此所有控制器都通过它运行。我在控制器上有一个动作,我不希望运行属性代码。我该如何实现呢?
[MyAttribute]
public class BaseController : Controller
{
}
public class WebPageController : BaseController
{
//How to override attribute executing here?
public ActionResult Index()
{
//do stuff
}
}
public class PagePermissionAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//Do stuff
}
}
答案 0 :(得分:4)
我完全误解了这个问题所以我删除了之前针对行动继承的答案。
为了在派生控制器中的动作上省略过滤器,我想我会以不同的方式处理它。一个想法就是拥有你的过滤器 - 如果你使用的是内置过滤器,你需要从中导出一个自定义过滤器 - 在运行之前使用反射检查是否存在另一个属性。在属性可用的情况下,它根本不执行。
public class SkipAuthorizeAttribute : Attribute
{
public string RouteParameters { get; set; }
}
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization( AuthorizationContext filterContext )
{
var action = filterContext.RouteData["action"];
var methods = filterContext.Controller
.GetType()
.GetMethods()
.Where( m => m.Name == action );
var skips = methods.GetCustomAttributes(typeof(SkipAuthorizeAttribute),false)
.Cast<SkipAuthorizeAttribute>();
foreach (var skip in skips)
{
..check if the route parameters match those in the route data...
if match then return
}
base.OnAuthorization();
}
}
用法:
[CustomAuthorize]
public class BaseController : Controller
{
...
}
public class DerivedController : BaseController
{
// this one does get the base OnAuthorization applied
public ActionResult MyAction()
{
...
}
// this one skips the base OnAuthorization because the parameters match
[SkipAuthorize(RouteParameters="id,page")]
public ActionResult MyAction( int id, int page )
{
...
}
}