12

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?

Robert Koritnik
  • 103,639
  • 52
  • 277
  • 404

2 Answers2

12

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.

Kiran
  • 56,921
  • 15
  • 176
  • 161
  • You're right about the *controller* part. In this case I was using a static URL segment instead of a variable. True. **I just thought that there would be some less verbose way** to achieve the same thing. Apparently there isn't any. You've somewhat written similarly verbose code than I did... I was hoping for less. :) – Robert Koritnik Dec 12 '13 at 13:01
  • True, but the thing is you are in general going to have only one route in the whole application where you would want a request to match `GET /` and so it would be verbose only in that situation and for the rest of the app you can use pattern like `[RoutePrefix("Home")][Route("{action=Index}")]`..do you agree? – Kiran Dec 12 '13 at 14:58
  • Of course I agree. And To think of it, we don't really need "/", "/Home" and "/Home/Index" to point to the same page. "/" is enough. We had the last couple because routing used to work this way. Having only one makes it simpler for canonisation. I'll therefore disregard them and not provide them in the first place. – Robert Koritnik Dec 13 '13 at 06:46
  • 1
    Sure `/` would be enough, but I was just demonstrating what you already wanted to do otherwise this whole question wouldn't come into picture – Kiran Dec 13 '13 at 07:09
  • I didn't need the `"{action}"` route on my class. And then I just added `[Route("~/"), Route("index")]` to my method. – eth0 Feb 10 '14 at 16:44
0

right now for SEO you should use canonical url meaning single url something like this

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

   public ActionResult ...
}

so home controller is accessible at root only

Asad Ali
  • 111
  • 2
  • 7
  • 1
    How is this answering the question? The question isn't asking about recommendations, but how to do specific thing... – Robert Koritnik Jan 26 '16 at 05:49
  • well there are no alternatives - attribute routing is alternative to old fashioned routing. We should recommend better ways always so people can learn the most – Asad Ali Jan 26 '16 at 13:48