How to execute Action Filter before Authorization Filter MVC 4

橙三吉。 提交于 2019-12-05 20:48:26

问题


I have implemented my own custom Authorization Attribute in MVC 4 by inheriting from AuthorizeAttribute class. I also have a custom ActionFilterAttribute. These both work fine however the problem lies in ordering them. I need the custom Action Filter to run before the custom Authorize Filter.

I have tried using the Order property for the attributes but as i understand it, Authorize Filters will always run before Action Filters.

Does anyone know how to force the Action Filter to execute before the Authorize Filter??


回答1:


When you take a look at the source code (available at http://aspnetwebstack.codeplex.com/) you see that this is not possible with the standard Filter classes. IAuthorizationFilter implementations are always executed before IActionFilter implementations. That's because action filters will not run when authorization filters return a result.

To solve this you can create your own ControllerActionInvoker descendant class and override the InvokeAction method:

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
        }
    }
}

You need to inject your custom MyControllerActionInvoker class into your controllers in a custom ControllerFactory class:

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;
    }
}

And of course you now have to register your own MyControllerFactory with the MVC framework. You should do this where you're also registering your routes:

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

This implementation works fine here.



来源:https://stackoverflow.com/questions/11496561/how-to-execute-action-filter-before-authorization-filter-mvc-4

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!