I have an interesting situation that has me stumped.
It seems that posting appliction/json content type makes the basic routing engine unable to bind action method arguments.
Using the default route:
Routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
I have an action method that looks like this:
//Controller name: TestController
[HttpPost]
public ActionResult SaveItem(int id, JsonDto dto)
{
// if content type of the request is application/json id = 0, JsonDto is populated
// if content type of the request is application/x-www-form-urlencode id = 1
}
I am posting to this url /Test/SaveItem/1 + the json object.
The reason that I need to id and the JsonDto is that the id argument references the parent object that the JsonDto object need to releate to.
I suppose I could change the dto to contain the parent id as a property and work around this whole problem.
It just strikes me as strange that the id argument does not get populated when I post a application/json request.
I have figured out my problem.
The problem is that the Json data that is being posted to the action method includes an
Idproperty, in addition to the
idroute value from the default route. So when binding the JSONobject, its
Idproperty wins over the route value in the URL. So to tweak Darin’s example:When the action method exectures, the
int idargument contains 456 and not 123 as I(apparently mistakenly) expected.
So the workaround for me was to change my default route to:
Renaming the default
idroute parameter tourlIdand updating my action methods solved theconflict for me.