Как игнорировать текущие значения маршрута при генерации ссылок? - PullRequest
15 голосов
/ 30 июня 2011

Вопрос похож на asp.net mvc Html.ActionLink () с сохранением значения маршрута, которое я не хочу , но с поворотом, который делает его более сложным.

Начиная сновое приложение MVC3 по умолчанию, я изменяю маршруты на:

routes.MapRoute(
    "r1", // Route name
    "{controller}/{id}/{action}"
);

routes.MapRoute(
    "r2", // Route name
    "{controller}/{action}"
);

Обратите внимание, что идентификатор идет перед действием в первом.

Затем в Home \ Index.cshtml я добавляю:

@Url.Action("Index")
@Url.Action("Index", new { id = "blah" })
@Url.Action("Index", new { id = "" })

Теперь я перехожу к / Home / Foo / Index и смотрю на 3 сгенерированных ссылки.Я получаю

  1. "/ Home / Foo / Index"
  2. "/ Home / blah / Index"
  3. "/ Home / Index? Id = Foo"

Первые два имеют смысл и используют первый маршрут.

Но в третьей ссылке, которая пересекает второй маршрут, я не понимаю, почему передается id = Fooв строке запроса, учитывая, что я явно передал пустой идентификатор.Я ожидал бы, что он просто сгенерирует "/Home/Index".

Может кто-нибудь объяснить это и предложить, как я могу заставить его не появляться?

Ответы [ 4 ]

20 голосов
/ 30 июня 2011

Я только что проверил это, и, кажется, работает нормально.

Url.Action("Index", new { id = UrlParameter.Optional })

создает * * +1004

/Home/Index
6 голосов
/ 30 июня 2011

Решить ее в этом случае довольно просто, если вам все равно, как она решается.

Измените третью ссылку на:

@Url.RouteUrl("R2")

, которая дает мне:

  • / Home / Foo / Index
  • / Home / blah / Index
  • / Home / Index

Почему это происходит в первом случаеэто то, что мне еще предстоит выяснить.Меня это тоже укусило, но в основном это касалось форм.

ОБНОВЛЕНИЕ 1:

Я копался в источнике MVC и создал несколько тестов, которые воспроизводилиЭта проблема.Кажется, проблема в том, что

RouteCollection.GetVirtualPath(requestContext, correctedValues);

запущен.Создает строку запроса со старым идентификатором.Именно поэтому я не могу сказать, поскольку этот класс не находится в источнике MVC.

5 голосов
/ 30 июня 2011

Вероятно, это не тот ответ, который вы ищете, но использование Url.Route вместо Url. Действие похоже работает:

@Url.RouteUrl("r2")

Это генерирует /Home/Index

Обновление

Фил Хаак рекомендует создание URL-адресов с использованием имени маршрута:

Это может показаться большой проблемой, но на самом деле это исправлениеочень просто. Используйте имена для всех ваших маршрутов и всегда используйте имя маршрута при генерации URL. Большую часть времени, позволяя маршрутизации разобраться, какой маршрут вы хотите использовать для генерации URL, действительно оставляет его на волю случая.При создании URL вы, как правило, точно знаете, на какой маршрут хотите ссылаться, поэтому вы можете также указать его по имени.

1 голос
/ 30 июня 2011

Поскольку r2 не определяет параметр id как часть URL? Если вы измените его на {controller} / {action} / {id}, все будет хорошо. Вы увидите то же поведение, если вы измените r2, чтобы не включать действие: тогда действие также станет переменной запроса.

Тот факт, что вы явно задаете для него значение "", означает, что маршрутизация все равно будет учитывать это. Просто не добавляйте идентификатор, и вы будете в порядке при создании ссылки.

...