9

我通过从AuthorizeAttribute类继承在 MVC 4 中实现了我自己的自定义授权属性。我也有一个习惯ActionFilterAttribute。这些都可以正常工作,但问题在于订购它们。我需要在自定义授权过滤器之前运行自定义操作过滤器。

我曾尝试使用Order属性的属性,但据我了解,授权过滤器将始终在操作过滤器之前运行。

有谁知道如何强制操作过滤器在授权过滤器之前执行?

4

1 回答 1

10

当您查看源代码(可在http://aspnetwebstack.codeplex.com/获得)时,您会发现标准过滤器类无法做到这一点。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
        }
    }
}

您需要将自定义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;
    }
}

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

var controllerFactory = new MyControllerFactory();
ControllerBuilder.Current.SetControllerFactory(controllerFactory);

这个实现在这里工作得很好。

于 2012-08-27T19:47:39.473 回答