应用于所有操作的 ActionMethodSelectorAttribute



我希望我的选择器应用于所有操作,但我不想将其复制并粘贴到任何地方。

[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。有什么想法吗?

我认为这是某种挑战 - 尝试将自定义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();
    }
}

现在就是这样:)

您可以将其更改为以下内容:

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

相关内容

  • 没有找到相关文章

最新更新