I currently have 2 areas in my ASP .NET MVC 5 project. One is called Supporters, and one is called Chatter. In each of these two areas, there is an ApiController
named CommunicationController
, and this poses a problem due to the nature of how an ApiController
works with routing.
If I had just one ApiController
named CommunicationController
in an area, its routing wouldn't include the area in the URL, and the URL would be something like this:
http://example.com/api/communication/someAction
But in the above URL, where is the area?
Since two of my controllers are named the same, they both have routing issues now.
I tried following the instructions here: http://blogs.infosupport.com/asp-net-mvc-4-rc-getting-webapi-and-areas-to-play-nicely/
They seem to apply for ASP .NET MVC 4 RC, which is no longer relevant since I am using MVC 5, and that might be why it wasn't working.
However, to recap from that blogpost, here are my routing files.
App_Start\RouteConfig.cs
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute("Default", "{controller}/{action}",
new {action = "Index", controller = "Home"},
new[] { "Website.Controllers" }
);
}
}
App_Start\WebApiConfig.cs
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
//the two lines below were added.
config.Routes.MapHttpRoute("SupportersApi", "api/supporters/{controller}/{id}", new {id = RouteParameter.Optional, area = "Supporters"}
);
config.Routes.MapHttpRoute("ChatterApi", "api/chatter/{controller}/{id}", new { id = RouteParameter.Optional, area = "Chatter" }
);
}
}
Areas\Chatter\ChatterAreaRegistration.cs
public class ChatterAreaRegistration : AreaRegistration
{
public override string AreaName
{
get { return "Chatter"; }
}
public override void RegisterArea(AreaRegistrationContext context)
{
//the below line was added.
context.Routes.MapHttpRoute("Chatter_api", "api/chatter/{controller}/{id}", new { id = RouteParameter.Optional, area = "Chatter" }
);
context.MapRoute(
"Chatter_default",
"Chatter/{controller}/{action}/{id}",
new {action = "Index", id = UrlParameter.Optional}
);
}
}
Areas\Supporters\SupportersAreaRegistration.cs
public class SupportersAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Supporters";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
//the below line was added.
context.Routes.MapHttpRoute("Supporters_api", "api/supporters/{controller}/{id}", new { id = RouteParameter.Optional, area = "Supporters" }
);
context.MapRoute(
"Supporters_default",
"Supporters/{controller}/{action}/{id}",
new { action = "Index", controller = "Home", id = UrlParameter.Optional }
);
}
}
What am I doing wrong here, and what are my options?
Use the WebAPI 2 attributes, since you are using MVC 5, and you can get rid of a lot of that boilerplate code by declaring the routes for your API along with it's implementation (you can also specify verbs for HTTP actions, and even use attributes to auto-convert to XML/JSON/serialization-of-the-month).
Unless you are using areas for some other reason, you really don't need them to implement a Web API.
In particular, what you want is the RoutePrefix attribute.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With