Reputation: 32758
After going this excellent blog post by Simon I came to know that model binding happens earlier than filters execution (even before authorization filters). If the request is not authorized then it should be rejected as earlier as possible and in that case I prefer running the authorization filters before the model binding process. Also, by this way we could save the time avoiding scanning the request, creating model instances and performing validation.
Is there any reason that I simply don't understand why the MVC request processing pipeline is designed such a way that the model binding should happen before filters?
Upvotes: 10
Views: 4030
Reputation: 835
In asp.net mvc3, the authorization filters execute before the model binding, not after (see code below).
Model binding occurs before the filters because the ActionExecutingContext (parameter of IActionFilter.OnActionExecuting) contains the action's parameters. Maybe they should have lazy loaded those parameters.
The following code is from the 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
}
Upvotes: 7