Why does MVC 4 Web API match action parameters from GET request body?
I have an API method that returns a user object by specifying the user id in a url request like this:
My route looks like this:
routes.MapHttpRoute(
"GetUserByUserId",
"users/{id}",
defaults: new { Controller = "User", Action = "GetUserByUserId" },
constraints: new { httpMethod = new HttpMethodConstraint(new string[] { "GET" })
});
The controller is called UserController and the method is called GetUserByUserId and looks like this:
[HttpGet]
public User GetUserByUserId(int id)
{
... returns a User object ....
}
If I call the method, it responds with a custom object as expected. The "1" in the URL is automatically mapped to the GetUserByUserId "id" attribute on the route.
But (!!) if I accidentally also provided a serialized JSON object of any type in the request body, e.g .:
{"Id":6,"PermissionId":0,"UserId":3}
MVC automatically maps the "Id" property in the request body object to my "id" attribute of the GetUserByUserId method, ignoring the id "1" in my url!
It looks very strange to me. I know Web API automatically maps the request url and request body to the corresponding attributes in the routed method, but the "Id" in the request element in my example is NOT a simple stand-alone integer, it is a complex type property and should not be interpreted as an attribute method "id".
Is this a bug or am I missing something?
source to share
asp.net mvc uses ValueProviderFactories to retrieve values ββfrom a model binding request. You can see the configured providers by checking the ValueProviderFactories.Factories property . With the default setting, this collection consists of
- ChildActionValueProviderFactory
- FormValueProviderFactory
- JsonValueProviderFactory
- RouteDataValueProviderFactory
- QueryStringValueProviderFactory
- HttpFileCollectionValueProviderFactory
This collection is sorted, and because it JsonValueProviderFactory
appears higher in the list, it is used as a value provider for id
, not RouteDataValueProviderFactory
.
source to share