Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting an ApiController to work with areas?

Tags:

c#

asp.net-mvc

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.

An example of the problem

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.

What have I tried?

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?

like image 924
Mathias Lykkegaard Lorenzen Avatar asked Aug 15 '14 19:08

Mathias Lykkegaard Lorenzen


1 Answers

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.

like image 191
Clever Neologism Avatar answered Oct 22 '22 21:10

Clever Neologism