Допустим, у вас есть метод действий для отображения продуктов в корзине покупок.
// ProductsController.cs
public ActionMethod Index(string gender) {
// get all products for the gender
}
В другом месте, в мачте, который отображается на каждой странице, вы используете Url.RouteUrl
для создания ссылок HREF на другие страницы сайта:
<a href="<%= Url.RouteUrl("testimonials-route", new { }) %>" All Testimonials </a>
Этот testimonials-route
определяется в global.ascx
первым маршрутом ниже.
Обратите внимание, что приведенный выше вызов RouteUrl
не предоставляет gender
, но маршрут определяется по умолчанию как "нейтральный", поэтому мы ожидаем, что будет вызван отзыв .Index( "нейтральный" ).
routes.MapRoute(
"testimonials-route",
"testimonials/{gender}",
new { controller = "Testimonials", action = "Index", gender = "neutral" },
new { gender = "(men|women|neutral)" }
);
routes.MapRoute(
"products-route",
"products/{gender}",
new { controller = "Products", action = "Index", gender = (string)null },
new { gender = "(men|women|neutral)" }
);
Если кто-то посещает страницу /products/women
, мы получаем HREF до /testimonials/women
Если кто-то посещает страницу /products
, тогда мы получаем пустой HREF (вызов RouteUrl возвращает null).
Но это не имеет смысла? testimonials-route
по умолчанию используется для 'neutral'
для нас, если мы не укажем для него значение маршрута?
Что получается, так это то, что вспомогательное расширение Url.RouteUrl(routeName, routeValues)
сначала будет искать в своем параметре routeValues
для значения маршрута gender
, и если он не найдет его в этом словаре, он будет смотреть на текущий URL-адрес, который мы находимся (помните, что Url - это объект UrlHelper, который имеет контекст текущего доступного ему запроса).
Это может иметь приятный эффект от предоставления нам ссылки на отзывы мужчин, если мы находимся на странице продукта для мужчин, но это, вероятно, не то, что мы хотим, если мы не передали значение в вызове RouteUrl
, и явно указывается "нейтраль" в качестве значения по умолчанию в файле global.asax.cs
.
В случае, когда мы посетили /products/
, мы вызвали маршрут 'products-route'
, и был вызван метод Products(null)
. Вызов Url.RouteUrl()
на самом деле наследует это значение null для gender
, когда мы создаем URL-адрес, используя testimonials-route
. Несмотря на то, что мы указали значение по умолчанию для gender
в 'testimionials-route
', оно все еще использует это нулевое значение, которое приводит к сбою маршрута и RouteUrl
возвращает значение null. [note: маршрут не работает, потому что у нас есть ограничение на (men | women | neutral), а null не подходит, что]
На самом деле становится более страшно - в том, что "контроллер" и "действие" могут быть унаследованы одинаково. Это может привести к тому, что URL-адреса генерируются полностью неверным контроллером даже при вызове RouteUrl (...) с явным именем маршрута, имеющим контроллер по умолчанию.
В этом случае, как только вы это выяснили, вы можете легко устранить его разными способами, но в других случаях это может привести к некоторому опасному поведению. Это может быть по дизайну, но это определенно страшно.