9

AuthorizeAttributeクラスから継承することにより、MVC4に独自のカスタム承認属性を実装しました。カスタムもありますActionFilterAttribute。これらは両方とも正常に機能しますが、問題はそれらを注文することにあります。カスタム認証フィルターの前にカスタムアクションフィルターを実行する必要があります。

属性にプロパティを使用してみOrderましたが、理解しているように、承認フィルターは常にアクションフィルターの前に実行されます。

承認フィルターの前にアクションフィルターを強制的に実行する方法を知っている人はいますか?

4

1 に答える 1

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

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 に答える