我希望我的选择器应用于所有操作,但我不想将它复制并粘贴到任何地方。
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public abstract class ActionMethodSelectorAttribute : Attribute
public class VersionAttribute : ActionMethodSelectorAttribute
{
public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
{
//my logic here
}
}
GlobalFilterCollection.Add
在这种情况下不起作用,因为它不是FilterAttribute
。有什么想法吗?
答案 0 :(得分:2)
我认为这是一种挑战 - 尝试将自定义ActionMethodSelector
注入现有列表中。 虽然我没有找到任何防弹方法来做到这一点,但我会分享我的想法
1.创建自定义ActionInvoker
并尝试注入选择器。我使用了默认的ReflectedActionDescriptor
,因为它已经包含MethodInfo
来测试MyActionMethodSelector
。
public class MyActionInvoker : ControllerActionInvoker
{
protected override ActionDescriptor FindAction(ControllerContext controllerContext, ControllerDescriptor controllerDescriptor, string actionName)
{
var action = base.FindAction(controllerContext, controllerDescriptor, actionName);
if (action != null)
{
var reflectedActionDecsriptor = action as ReflectedActionDescriptor;
if (reflectedActionDecsriptor != null)
{
if (new MyActionMethodSelectorAttribute().IsValidForRequest(controllerContext, reflectedActionDecsriptor.MethodInfo))
{
return null;
}
}
}
return action;
}
}
2.将MyActionInvoker
注入控制器。为此,从MyBaseController
派生所有控制器,实现为
public class MyBaseController : Controller
{
protected override IActionInvoker CreateActionInvoker()
{
return new MyActionInvoker();
}
}
现在就是这样:)
答案 1 :(得分:1)
您可以将其更改为以下内容:
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class VersionAttribute : FilterAttribute, IActionFilter
{
private bool IsValidForRequest(ActionExecutingContext filterContext)
{
//my logic here
return true; //for testing
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
if (!IsValidForRequest(filterContext))
{
filterContext.Result = new HttpNotFoundResult(); //Or whatever other logic you require?
}
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
//left blank intentionally
}
}
然后将其注册为全局过滤器:
filters.Add(new VersionAttribute());