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:

http://www.myapi.com/users/1

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?

+3


source to share


1 answer


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

.

+3


source







All Articles