Как зарегистрировать область, используя app_start или webactivator?
Я хотел бы избежать необходимости звонить
AreaRegistration.RegisterAllAreas()
в моем global.asax, потому что я пытаюсь переместить всю логику запуска в отдельные классы внутри папки App_Start. Тем не менее, мне не удалось заставить это работать. Первый вариант попытался использовать код, подобный этому:
[assembly: PreApplicationStartMethod(typeof(Startup), "PreInit")]
namespace Foo
{
public class Startup {}
}
Где PreApplicationStartMethod происходит из пространства имен System.Web. В этом случае вызов для регистрации областей происходит слишком рано.
Второй подход, основанный на этом посте Дэвида Эббо, использует WebActivator: using System.Web.Mvc;
[assembly: WebActivatorEx.PostApplicationStartMethod
(typeof(AreaDemo.AreaConfig), "RegisterAreas")]
namespace AreaDemo
{
public class AreaConfig
{
public static void RegisterAreas()
{
AreaRegistration.RegisterAllAreas();
}
}
}
К сожалению, хотя ошибки не выдаются, попытка перейти в этот район не удалась (как если бы регистрация никогда не происходила).
Как правильно зарегистрировать области в ASP.NET MVC 5 из класса запуска, используя директиву сборки, а не прямой вызов из Global.asax?
Обновление 1: Вот мой код регистрации зоны:
public class AdminAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Admin";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new string[] { "AreaDemo.Areas.Admin.Controllers" }
);
}
}
По какой-то причине настройки по умолчанию игнорируются, но переход к /admin/home/index/0 работает. / admin, / admin / home и / admin / home / index все 404.
1 ответ
Я полагаю, что это проблема заказа (что, кажется, вы тоже подозреваете). Я думаю, что районы регистрируются после Application_Start
событие, и, таким образом, маршруты областей регистрируются после маршрутов вне зоны.
Причина в том, что 4-х сегментный URL (/admin/home/index/123
) работает так, что он не может соответствовать маршруту по умолчанию приложения MVC. Таким образом, этот маршрут по умолчанию пропускается (поскольку он соответствует только 1-, 2- и 3-сегментным URL-адресам), и при маршрутизации будет найден маршрут для конкретной области, который может обрабатывать 4-сегментный URL-адрес. 1-, 2- или 3-сегментный URL будет соответствовать необластному маршруту, но, конечно, за пределами областей нет контроллеров для обработки такого URL, и поэтому возвращается 404.
Если я правильно понял, вы хотите, чтобы районы были зарегистрированы после Application_Start
, но прежде чем что-то еще произойдет? К сожалению, я не знаю ни одного конкретного события, чтобы справиться с этим. Из IHttpModule
Вы можете попробовать обработать событие, такое как BeginRequest
, что происходит очень рано, быстро выполните регистрацию там только один раз (то есть, не регистрируйте вещи по каждому запросу!), и это должно позволить вам проникнуть до того, как ASP.NET Routing сделает свое дело (что происходит немного позже, во время PostResolveRequestCache
).
Полная альтернатива этому заключается в использовании атрибутных маршрутов, которые нравятся многим, потому что это может помочь избежать проблем с упорядочением.