Reputation: 8164
I have a controller function which accepts a strongly typed model as parameter. When i enter ANY url mapping to the controller but not on a specific action on the post request , then the controller executes this function instead of returning a 404 code.
When i Change the function's parameter to a primitive type variable then the problem does not occur. (i have tried using other strongly typed models as parameters and again the problem occurs)
Here's the function.
public class PhoneApiController : ApiController
{
[HttpPost]
public HttpResponseMessage RegisterApp(RegisterAppInfo appInfo)
{
var resp = Request.CreateResponse(HttpStatusCode.OK, new
{
Success = true,
AppId = 1000,
IdAlias = "QAUBC9",
appInfo = appInfo
});
return resp;
}
}
So when i enter for example localhost:51464/Api/PhoneApi/Sajsdkasjdklajsasd
the function executes normally.!
I am using the default Route config
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
I don't know if this is a bug or i am doing something wrong.
Upvotes: 1
Views: 808
Reputation: 5585
For MVC 4.5 this is the only thing that works
There is currently a bug about this.
Below is a work around in order to get the following route types work
api/{controller}/ //Get All
api/{controller}/{Id} //Get for id
api/{controller}/{Id}/{Action}/ //Get all for action for controller with Id
you need to do the following.
Change your routing over to. (Note the default action..)
config.Routes.MapHttpRoute(
name : "DefaultAPi",
routeTemplate : "api/{controller}/{id}/{action}",
defaults: new
{
id = RouteParameter.Optional,
action = "DefaultAction"
}
);
In your controller change the base methods over to
[ActionName("DefaultAction")]
public string Get()
{
}
[ActionName("DefaultAction")]
public string Get(int id)
{
}
[ActionName("SpaceTypes")]
public string GetSpaceTypes(int id)
{
}
Now everything should work as expected..
Thanks to Kip Streithorst full this, for a full explanation
Upvotes: 3
Reputation: 19311
The URI /Api/PhoneApi/Sajsdkasjdklajsasd
does match your route template api/{controller}/{id}
with {controller}
matching PhoneApi
and {id}
matching Sajsdkasjdklajsasd
. I assume you are making a POST to this URI. So, Web API is mapping your request to the action method RegisterApp
with [HttpPost]
in the controller class PhoneApiController
.
As far as the junk stuff in the URI, it gets mapped to {id}
. But your parameter is RegisterAppInfo
, which is a complex type and that gets bound from request body and not the URI. That's why it works when you have the complex type. The simple types are bound from URI, query string.
If you have the action method as public HttpResponseMessage RegisterApp(string id, Abc appInfo)
, you will see that this id
parameter gets populated with "Sajsdkasjdklajsasd".
Upvotes: 3
Reputation: 6622
The way routing works in Web API is:
By default, Web API tries to bind "simple" parameter types (like int) from the URI, and tries to read complex types from the request body.
See here for details: http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-and-action-selection
Upvotes: 0