ASP.NET MVC: How does a controller distingush between parameters in the URL and sent by POST

asp.net-mvc, c#, model-binding

Solution

Take a look at the default route from `Global.asax`:

routes.MapRoute(
    "Default",                                            
    "{controller}/{action}/{id}",                     
    new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

The first thing that MVC will try to do is map your method parameters to values in the POST. If it doesn't find a match, it will cascade through other possibilities, including the route values.

Here's the order the model binder uses:

- Previously bound action parameters, when the action is a child action

- Form fields (Request.Form)

- The property values in the JSON Request body (Request.InputStream), but only when the request is an AJAX request

- Route data (RouteData.Values)

- Querystring parameters (Request.QueryString)

- Posted files (Request.Files)

The reason you're seeing the behaviour you describe is because POST data comes before route values. It seems that MVC can't bind a nullable int to a POST value, so it skips over it and keeps going until it reaches the `RouteData` mapping, at which point, it finds a match and gets the value from the route. When you make the parameter non-nullable, it is suddenly able to bind it to the POST value, which has higher precedence than `RouteData`, so it does.

Source: http://msdn.microsoft.com/en-us/magazine/hh781022.aspx

Problem

I would like to better understand how a controler method knows when a parameter it recives should be retrived from the post data or the url. Take the following example: ``` URL: /ModelController/Method/itemID // Where itemID is the id (int) of the item in the database POST: objectOrArray: {JSON Object/Array} ``` The controller would look something like this: ``` [HttpPost] public ActionResult InputResources(int? id, Object objectOrArray) ``` Now, somehow the method is smart enough to look for the first parameter, the `id`, in the site URL and the `Object` in the `HTTPPost`. Whilst this works, I don't know why, and as a result I sometimes run into unpredictable and erratic behaviour. For example, I seem to have found (although I am not 100% sure) that removing the `?` from `int? id` makes the controller method inmediately assume it should look for the id in the `HTTPPost` and not the URL. So I would like to clarify the following points: What exactly is it that tells the method where to look for the data? (The `[HttpPost]` attribute preciding the method?) Do naming conventions come into play? (for example removint the `?` or not using `id` as the variable name?) Does the order in which the variables are placed have an inpact? (ie placing the `Object` before the `id`) I know I can more or less figure out some of this stuff by trial and error, but I would like a qualified explanation rather than to continiue to work of assumption based on observation. Thank you Chopo

Original source