У меня и моего друга была такая же проблема с областями в ASP.NET MVC 2. Мы нашли «хак», который, похоже, работает. Версия tl; dr приведена в нижней части этого ответа.
Возможно, у вас есть что-то похожее на следующее в классе AdminAreaRegistration.cs вашей области:
// Web/Areas/Admin/AdminAreaRegistration.cs
public override void RegisterArea(AreaRegistrationContext context) {
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
Таким образом, должно иметь смысл, что когда вы делаете запрос для "http://website/Abstract",", маршрут "Admin_default" не совпадает с запросом. Таким образом, структура MVC пытается сопоставить запрос с любым другим определенные маршруты. Если вы использовали инструмент MVC в Visual Studio для создания своего веб-проекта, у вас будет маршрут по умолчанию, определенный в файле «Global.asax» (в корне вашего веб-проекта). Он должен выглядеть аналогично на это:
// Web/Global.asax.cs
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new {controller = "Home", action = "Index", id = UrlParameter.Optional}
);
}
Маршрут "По умолчанию" успешно сопоставляет запрос для "http://website/Abstract", с" controller "=" Abstract "," action "=" Index "(значение по умолчанию) и" id "= UrlParameter.Optional (значение по умолчанию). Это правильное и предполагаемое поведение ... пока.
Теперь инфраструктура MVC попытается загрузить «абстрактный» контроллер. По замыслу MVC будет искать класс с именем «AbstractController», который расширяет «Controller» в любом месте иерархии файлов / пространств имен веб-проекта. Важно отметить, что местоположение файла и пространство имен Контроллера не влияют на способность MVC найти его; другими словами, просто потому, что вы поместили «AbstractController» в папку «Areas \ Admin \ Controllers» и изменили пространство имен на «Web.Areas.Admin.Controllers» вместо, скажем, «Web.Controllers» , не означает, что MVC не будет его использовать.
Когда MVC выполняет действие «Index» в «AbstractController», которое, скорее всего, просто возвращает «View ()», тогда MVC сбивается с толку, поскольку не знает, где найти представление «Index». Поскольку MVC совпал с необластным маршрутом (маршрут «По умолчанию» в Global.asax), он считает, что соответствующий вид должен находиться в папках беззонального представления. Таким образом вы получите знакомое сообщение об ошибке:
The view 'Index' or its master was not found. The following locations were searched:
~/Views/Abstract/Index.aspx
~/Views/Abstract/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
Мы, как и вы, не хотели, чтобы запросы для "http://website/Abstract" разрешались в" AbstractController "области администратора; должен работать только" http://website/Admin/Abstract". Я не могу понять, почему кто-то хотел бы такого поведения.
Простое решение состоит в том, чтобы удалить маршрут "Default" в Global.asax, , но , это нарушит все обычные не-зональные контроллеры / представления. Это, вероятно, не вариант для большинства людей ...
Итак, мы подумали, что можем ограничить набор контроллеров, которые MVC будет использовать для запросов, соответствующих маршруту «По умолчанию» в Global.asax:
// Web/Global.asax.cs
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new {controller = "Home", action = "Index", id = UrlParameter.Optional},
new[] {"Web.Controllers"} // Added this line
);
}
Неа. Запрос "http://website/Abstract" будет все еще использовать" AbstractController "в области" Администратор ", даже если пространство имен" AbstractController "равно" Web.Areas.Admin.Controllers "и ( очевидно, не "Web.Controllers". Это полностью сбивает с толку, кажется, что этот белый список не оказывает существенного влияния на разрешение контроллера MVC.
- tl; д-р ответ начинается здесь -
После некоторого взлома мы выяснили, как заставить MVC использовать контроллеры только в пространствах имен, включенных в белый список.
// Web/Global.asax.cs
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new {controller = "Home", action = "Index", id = UrlParameter.Optional},
new[] {"Web.Controllers"}
).DataTokens["UseNamespaceFallback"] = false; // Added this line
}
Установите ключ «UseNamespaceFallback» словаря DataTokens на маршруте «По умолчанию» в значение false. Теперь, когда мы сделаем запрос на «http://website/Abstract",», маршрут «По умолчанию» будет по-прежнему соответствовать (это допустимое поведение!), Но MVC не будет использовать любой контроллер, который не находится в пределах определенного namespace (s), в этом случае допустимы только контроллеры в пространстве имен "Web.Controllers". Наконец, это та функция, которую мы искали! Мы не можем понять, почему это не поведение по умолчанию. да?
Надеюсь, это поможет.