10

Simon によるこの優れたブログ記事を読んだ後、モデル バインディングはフィルターの実行よりも前に (承認フィルターの前であっても) 発生することを知りました。リクエストが承認されていない場合は、できるだけ早く拒否する必要があります。その場合、モデル バインディング プロセスの前に承認フィルターを実行することをお勧めします。また、この方法により、リクエストのスキャン、モデル インスタンスの作成、および検証の実行を回避する時間を節約できます。

MVC リクエスト処理パイプラインが、フィルターの前にモデル バインディングが発生するように設計されている理由を単純に理解できない理由はありますか?

4

1 に答える 1

7

asp.net mvc3 では、承認フィルターはモデル バインディングの後ではなく前に実行されます (以下のコードを参照)。

ActionExecutingContext (IActionFilter.OnActionExecuting のパラメーター) にアクションのパラメーターが含まれているため、フィルターの前にモデル バインディングが発生します。おそらく、それらのパラメーターを遅延ロードする必要があります。

次のコードは、System.Web.Mvc.ControllerActionInvoker からのものです。

public virtual bool InvokeAction(ControllerContext controllerContext, string actionName) 
{
    // code removed for brevity
    try 
    {
        // Notice the authorization filters are invoked before model binding
        AuthorizationContext authContext = InvokeAuthorizationFilters(controllerContext, filterInfo.AuthorizationFilters, actionDescriptor);
        if (authContext.Result != null) {
            // the auth filter signaled that we should let it short-circuit the request
            InvokeActionResult(controllerContext, authContext.Result);
        }
        else {
            if (controllerContext.Controller.ValidateRequest) {
                ValidateRequest(controllerContext);
            }
            // GetParameterValues does the model binding
            IDictionary<string, object> parameters = GetParameterValues(controllerContext, actionDescriptor);
            ActionExecutedContext postActionContext = InvokeActionMethodWithFilters(controllerContext, filterInfo.ActionFilters, actionDescriptor, parameters);
            InvokeActionResultWithFilters(controllerContext, filterInfo.ResultFilters, postActionContext.Result);
        }
    }
    // code removed for brevity
}
于 2012-12-07T18:57:10.900 に答える