6
votes

Using attribute based routing I would like to match the following routes:

~/
~/Home
~/Home/Index

to HomeController.Index, and this route:

~/Home/Error

to HomeController.Error. Here is my configuration:

[Route("[controller]/[action]")]
public class HomeController : Controller {
    [HttpGet, Route(""), Route("~/")]
    public IActionResult Index() {
        return View();
    }

    [HttpGet]
    public IActionResult Error() {
        return View();
    }
}

I have tried adding Route("[action]"), Route("Index"), and other combinations but still don't get a match for:

/Home/Index
2
FYI - Putting the same content on more than one URL and not using a canonical tag is bad for SEO. A better option to use a 301 redirect for /Home and /Home/Index to redirect all requests and bookmarks to /.NightOwl888
@NightOwl888 good comment, but this is for an internal web applicationB Z

2 Answers

12
votes

The empty route Route("") combines with the route on controller, use Route("/") to override it instead of combining with it:

[Route("[controller]/[action]")]
public class HomeController : Controller {

    [HttpGet]
    [Route("/")]
    [Route("/[controller]")]
    public IActionResult Index() {
        return View();
    }

    [HttpGet]
    public IActionResult Error() {
        return View();
    }
}

Alternatively, you can remove the /[action] on the controller, which makes it a bit easier (no need to override), but then you have to define a route on every action.

I'm assuming that you intentionally want to use attribute routing rather than conventional routing, so the above answer is what you need. However, just in case the assumption is wrong, this can be easily achieved with a simple conventional routing:

routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
2
votes
[Route("[controller]")]
   public class HomeController : Controller
   {
      [Route("")]     // Matches 'Home'
      [Route("Index")] // Matches 'Home/Index'
      public IActionResult Index(){}

      [Route("Error")] // Matches 'Home/Error'
      public IActionResult Error(){}

 }