Маршрутизация атрибутов в MVC 5 и необязательные значения по умолчанию


Традиционные значения по умолчанию маршрутизации означали, что мы могли получить доступ к этим URL-адресам и всегда заканчивались одним и тем же действием:

/
/Home
/Home/Index
Но сегодня мы бы написали что-то в этих строках:
[RoutePrefix("Home")]
[Route("{action=Index}")]
public class HomeController
{
    public ActionResult Index() {}

    public ActionResult ...
}
Но это определение маршрута ни в коем случае не одно и то же.
/           (fails)
/Home       (works)
/Home/Index (works)

Поэтому, если мы затем изменим верхний код на

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

    public ActionResult ...
}

Но затем мы переворачиваем обработку вверх ногами:

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

Мы могли бы сделать декларативный код более подробным и заставить его работать как старомодная маршрутизация механизм:

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

    public ActionResult ...
}
Это работает со всеми тремя различными маршрутами.

Вопрос

Эта проблема, конечно, связана с тем самым действием по умолчанию приложения, которое определяет контроллер и действие по умолчанию. Просто мне интересно, является ли это единственным способом сделать это?Есть ли какой-нибудь менее подробный кодовый способ заставить его работать, как ожидалось?

2 11

2 ответа:

Да, верно..то, что у вас есть, - это способ сделать здесь...

Я немного изменил код здесь:

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

   public ActionResult ...
}

Некоторые детали:
1. Ваш первый случай не совсем совпадает с обычной маршрутизацией, так как в этом случае у вас есть литеральный сегмент Home, который не похож на обычную маршрутизацию {controller}/{action}/{id} and controller = Home, action=Index,id=optional.
2. Ваш второй случай ожидается как по дизайну, если атрибут Route используется для действия, атрибуты на контроллере не вступают в силу.

Прямо сейчас для SEO вы должны использовать канонический url, то есть один url что-то вроде этого

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

   public ActionResult ...
}

Таким образом, домашний контроллер доступен только в корне