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?
as you can see from the below diagram, as soon as the controller starts execution through Action Invoker, Authentication and authorization filters are the very first filters to be triggered, followed by model binding which maps request and route data to action parameters.
How Model Binding Works. Model binding is a simplistic way to correlate C# code with an HTTP request. The model binding applies to transforming the HTTP request data in the query's form string and form collection of the action method parameters. We can consider these parameters to be primitive type or complex type.
Model binding is a process in which we bind a model to controller and view. It is a simple way to map posted form values to a . NET Framework type and pass the type to an action method as a parameter. It acts as a converter because it can convert HTTP requests into objects that are passed to an action method.
Filters are executed in the order listed above. For example, authorization filters are always executed before action filters and exception filters are always executed after every other type of filter. Authorization filters are used to implement authentication and authorization for controller actions.
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
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With