Я только что наткнулся на это в поисках информации по той же проблеме. Основная проблема заключается в том, что модель маршрутизации предназначена для работы с классом HttpApplication, который в основном представляет собой автоматически зарегистрированный экземпляр IHttpHandler с некоторым состоянием voodoo, а не с собственным IHttpModule, подобным тем, которые мы можем создать и зарегистрировать в web.config.
В моей попытке переместить трубопровод MVC из основного веб-проекта в IHttpModule я столкнулся с проблемой регистрации нескольких маршрутов, потому что, насколько я вижу, метод Init()
иногда выполняется более одного раза внутри домен приложения. Таким образом, к тому времени, когда пришел второй (или третий) вызов Init()
, в RouteTable уже было все на месте, и при попытке зарегистрировать дублирующиеся маршруты было сгенерировано исключение (в данном случае значение по умолчанию «Default»). Я не уверен, что вызывает это, поскольку я никогда не видел это в обычных проектах ASP.NET. Возможно, это что-то особенное для MVC.
(Очевидное) решение состоит в том, чтобы проверить количество уже зарегистрированных маршрутов и остановить его, если оно равно нулю:
public void Init(HttpApplication context) {
if (RouteTable.Routes.Count == 0) {
RouteTable.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
RouteTable.Routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
Это стандартный код, вставленный из Global.asax, добавленного в проект MVC по умолчанию, в реализации IHttpModule, которая находится в отдельной сборке.
Это работает, но я не чувствую любви. Кажется, что нужно приложить немало усилий, чтобы избавиться от Global.asax. Мне все еще нужно разделение проблем здесь - логика маршрута должна жить в отдельном классе. Но я предполагаю, что собираюсь использовать какой-то суррогатный шаблон, который создается в Global.asax на основе некоторого параметра конфигурации и вызывается по мере необходимости в зависимости от обрабатываемого события.
Надеюсь, это поможет кому-то поискать по телефону mvc MapRoute IHttpModule :)