如何在授权过滤器MVC 4之前执行操作过滤器

dav*_*990 8 custom-attributes asp.net-mvc-4

我通过继承自AuthorizeAttribute类在MVC 4中实现了自己的自定义授权属性.我也有一个习惯ActionFilterAttribute.这些都很好,但问题在于订购它们.我需要自定义Action Filter在自定义Authorize Filter之前运行.

我已尝试将Order属性用于属性,但据我了解,授权过滤器将始终在动作过滤器之前运行.

有谁知道如何在授权过滤器之前强制执行A​​ction Filter?

Car*_*tte 10

当您查看源代码(可从http://aspnetwebstack.codeplex.com/获得)时,您会发现使用标准的Filter类是不可能的.IAuthorizationFilter实现总是在IActionFilter实现之前执行.这是因为当授权过滤器返回结果时,动作过滤器不会运行.

要解决此问题,您可以创建自己的ControllerActionInvoker后代类并覆盖该InvokeAction方法:

public class MyControllerActionInvoker : ControllerActionInvoker
{
    public override bool InvokeAction(ControllerContext controllerContext, string actionName)
    {
        // Your initialization code here
        try
        {
            return base.InvokeAction(controllerContext, actionName);
        }
        finally
        {
            // Your finalization code here
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

您需要将自定义MyControllerActionInvoker类注入自定义类中的控制器ControllerFactory:

public class MyControllerFactory : DefaultControllerFactory
{
    private readonly MyControllerActionInvoker actionInvoker = new MyControllerActionInvoker();

    /// <summary>
    /// Retrieves the controller instance for the specified request context and controller type.
    /// </summary>
    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        var controllerInstance = base.GetControllerInstance(requestContext, controllerType);

        if (controllerInstance != null)
        {
            var typedController = controllerInstance as Controller;
            if (typedController != null)
            {
                typedController.ActionInvoker = this.actionInvoker;
            }
        }

        return controllerInstance;
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,您现在必须MyControllerFactory使用MVC框架注册自己的.您还应该在注册路线的地方执行此操作:

var controllerFactory = new MyControllerFactory();
ControllerBuilder.Current.SetControllerFactory(controllerFactory);
Run Code Online (Sandbox Code Playgroud)

这个实现在这里工作正常.