I'm presently working on a project that has been upgraded to Webapi2 from Webapi. Part of the conversion includes the switch to using attribute based routing.
I've appropriately setup my routes in the Global.asax (as follows)
GlobalConfiguration.Configure(config => config.MapHttpAttributeRoutes());
and removed the previous routing configuration.
I have decorated all of my API controllers with the appropriate System.Web.Http.RouteAttribute and System.Web.Http.RoutePrefixAttribute attributes.
If I inspect System.Web.Http.GlobalConfiguration.Configuration.Routes with the debugger I can see that all my expected routes are registered in the collection. Likewise the appropriate routes are available within the included generated Webapi Help Page documentation as expected.
Even though all appears to be setup properly a good number of my REST calls result in a 404 not found response from the server.
I've found some notable similarities specific to GET methods (this is all I've tested so far)
- If a method accepts 0 parameters it will fail
- If a route overrides the prefix it will fail
- If a method takes a string parameter it is likely to succeed
- return type seems to have no affect
- Naming a route seems to have no affect
- Ordering a route seems to have no affect
- Renaming the underlying method seems to have no affect
Worth noting is that my API controllers appear in a separate area, but given that some routes do work I don't expect this to be the issue at hand.
Example of non-functional method call
[RoutePrefix("api/postman")]
public class PostmanApiController : ApiController
{
...
[HttpGet]
[Route("all", Name = "GetPostmanCollection")]
[ResponseType(typeof (PostmanCollectionGet))]
public IHttpActionResult GetPostmanCollection()
{
return Ok(...);
}
...
}
I expect this to be available via http://[application-root]/api/postman/all
Interestingly enough a call to
Url.Link("GetPostmanCollection", null)
will return the above expected url
A very similar example of method calls within the same controller where some work and some do not.
[RoutePrefix("api/machine")]
public class MachineApiController : ApiController
{
...
[HttpGet]
[Route("byowner/{owner}", Name = "GetPostmanCollection")]
public IEnumerable<string> GetByOwner([FromUri] string owner)
{
...
}
...
[HttpGet]
[Route("~/api/oses/{osType}")]
public IEnumerable<OsAndVersionGet> GetOSes([FromUri] string osType)
{
...
}
...
}
Where a call to http://[application-root]/api/machineby/ownername
succeeds and http://[application-root]/api/oses/osType
does not.
I've been poking at this far too long, any idea as to what the issue may be?