So I was recently working on an existing ASP.NET MVC project when we decided to expose some of the app’s data to mobile applications using WebApi. How difficult can that be (adding WebApi to an existing MVC project). I mean you add the reference to the NuGet package Microsoft.AspNet.WebApi.Core
, which automatically adds all other NuGet packages needed and creates the WebApiConfig.cs
class for you with the default WebApi route registration.
You just need to ensure your method (by default named “Register
“) from WebApiConfig
is called from Application_Start
in Global.asax.cs
, and you should be all set creating and calling your ApiControllers
, right.
Not so in my case. Having done that and trying to invoke the ApiController
from browser was giving me 404 errors. I checked all usual stuff:
- The api routes were registered correctly
- I was invoking the right url
- The HTTP method was allowed on the api method (i.e. it had
[HttpGet]
attribute applied and the method was invoked as aGET
request only) - There was no parameter mismatch on the action method and its invocation
But it was not working. I checked and re-checked all common mistakes and even enabled route-debugging for my project as outlined in the referenced link but nothing could shed light on the 404 errors when trying to access webapi methods from my project.
Finally when comparing the WebApi code from this project with another project where WebApi was working successfully, I observed a minor difference. The other project had WebApi routes registered before the MVC controller method routes.
[code language=”csharp”]
WebApiConfig.Register(GlobalConfiguration.Configuration);
RouteConfig.RegisterRoutes(RouteTable.Routes);
[/code]
While my current project (where I was trying to add WebApi support) had WebApi routes registered after MVC routes:
[code language=”csharp”]
RouteConfig.RegisterRoutes(RouteTable.Routes);
WebApiConfig.Register(GlobalConfiguration.Configuration);
[/code]
Just changing the order of route registration where WebApiConfig.Register
was invoked before RouteConfig.RegisterRoutes
in Global.asax.cs
fixed things for me and WebApi started working in the new project too.
Thinking of it now, this makes sense. API paths usually start with hard-coded api
followed with {controller}
and {action}
names. When registering MVC routes first, it might be confusing MVC causing the api paths to be searched as an MVC controller with the name ApiController
.
However even adding the following line to RouteConfig.cs
(MVC’s route registration file by default) did not cause the api
paths to be ignored:
[code language=”csharp”]
routes.IgnoreRoute("api/{*pathInfo}");
[/code]
This really leaves me clueless on how WebApi and MVC are working in-tandem internally to resolve paths. Anyways, registering WebApi routes first and then MVC routes thereafter got things working for me fixing the 404 response codes for my api calls. It’s easy to overlook this especially when WebApi support is added to a project at a later stage after project creation (by default, if you choose a Visual Studio template that also creates WebApi scaffolded code during project creation, the template automatically registers WebApi routes before MVC routes in Global.asax
).
The attached sample project demonstrates this problem. In its current state, it won’t allow you access to “~/api/Account/Ping?name=Rahul
” but if you switch order of route registration in Global.asax.cs as outlined in this blog post, the api starts working.