Search code examples
asp.net-mvc-routingasp.net-mvc-5attributerouting

Attribute routing in MVC 5 and optional defaults


Traditional routing defaults meant we were able to access these URLs and always end up on the same action:

/
/Home
/Home/Index

But today we would be writing something in these lines:

[RoutePrefix("Home")]
[Route("{action=Index}")]
public class HomeController
{
    public ActionResult Index() {}

    public ActionResult ...
}

But this routing definition is by no means the same.

/           (fails)
/Home       (works)
/Home/Index (works)

So if we then change upper code to

[RoutePrefix("Home")]
[Route("{action=Index}")]
public class HomeController
{
    [Route("~/")]
    public ActionResult Index() {}

    public ActionResult ...
}

But then we turn the processing upside down:

/           (works)
/Home       (fails)
/Home/Index (fails)

We could make declarative code more verbose and make it work as the old-fashioned routing mechanism by:

[RoutePrefix("Home")]
[Route("{action=Index}")]
public class HomeController
{
    [Route("~/")]
    [Route("~/Home")]
    [Route("~/Home/Index")]
    public ActionResult Index() {}

    public ActionResult ...
}

This works with all three different routes.

Question

This issue is of course bound to the very application default action that defaults controller and action. It's just that I wonder whether this is the only way of doing it? Is there any less verbose code way of getting it to work as expected?


Solution

  • Yeah, right..what you have is the way to do here...

    I modified the code a bit here:

    [RoutePrefix("Home")]
    [Route("{action}")]
    public class HomeController
    {
       [Route("~/")]    // GET /
       [Route]          // GET /Home
       [Route("Index")] // GET /Home/Index
       public ActionResult Index() {}
    
       public ActionResult ...
    }
    

    Some details:
    1. Your first case is not exactly the same as conventional routing as in this case you have a literal segment Home which is not similar to the conventional routing optional of {controller}/{action}/{id} and controller = Home, action=Index,id=optional.
    2. Your second case is expected as by design if a Route attribute is used on action the attributes on Controller do not take effect.