Search code examples
asp.netasp.net-mvcasp.net-mvc-5asp.net-mvc-routing

Asp.Net MVC 5 custom action routing under an area


i am currently trying to generate this url "/Cloud/Hosting/RoaringPenguin/Manage/Exclusions".

Here is the area registration

public override void RegisterArea(AreaRegistrationContext context) 
    {
        context.MapRoute(
            "Hosting_default",
            "Cloud/Hosting/{controller}/{action}/{id}",
            new { action = "Index", id = UrlParameter.Optional }
        );
    }

here is the controller

    public class RoaringPenguinController : PortalControllerBase
{


    public ActionResult Exclusions()
    {
        return View("Exclusions");
    }


}

i have tried added a route onto the action itself like so

[Route("Manage/Exclusions")]
public ActionResult Exclusions()

I have also tried adding some attributes to the controller itself

[RouteArea("Hosting")]
[RoutePrefix("RoaringPenguin")]
public class RoaringPenguinController : PortalControllerBase

but that doesn't seem to work either. If i leave all the attributes off then the final url i get is "/Cloud/Hosting/RoaringPenguin/Exclusions". Does anyone know how i can get the "Manage" in the url as well?

Just to confirm i have the following set in my RegisterRoutes method under the RouteConfig class

routes.MapMvcAttributeRoutes();

Any help is appreciated. Thanks


Solution

  • Your default area route doesn't allow for the "Manage/Exclusions" part on the end. If you made the URL just /Cloud/Hosting/RoaringPenguin/Exclusions (minus the Manage part of the path) it would work fine.

    If you need the route to be exactly that, then attribute routing is your best bet. However, your mentioned attempts at that are all missing something or another. Your controller should be decorated with both RouteArea and RoutePrefix to compose the first part of the path:

    [RouteArea("Hosting", AreaPrefix = "Cloud/Hosting")]
    [RoutePrefix("RoaringPenguin")]
    public class RoaringPenguinController : Controller
    

    However, it's typical to actually implement a base controller when dealing with areas, so that you can specify RouteArea in just one place:

    [RouteArea("Hosting", AreaPrefix = "Cloud/Hosting")]
    public class HostingBaseController : Controller
    
    [RoutePrefix("RoaringPenguin")]
    public class RoaringPenguinController : HostingBaseController
    

    Then, on your action:

    [Route("Manage/Exclusions")]
    public ActionResult Exclusions()
    

    As you had.