MVC 2 ОбластьРегистрация Маршруты Заказ - PullRequest
12 голосов
/ 28 октября 2009

Я заметил, что в MVC 2 Preview 2 AreaRegistration загружает маршруты для каждой области в произвольном порядке. Есть ли хороший способ получить один раньше другого?

Например, у меня есть две области - «Сайт» и «Администратор». Оба имеют контроллер «Блог».

Хотелось бы следующее:

/admin/ --> go to Admin's Blog controller
/       --> go to Site's Blog controller. 

Проблема в том, что он сначала загружает маршрут сайта, поэтому он совпадает с {controller}/{action}/{id} вместо admin/{controller}/{action}/{id}, когда я перехожу по URL "/ admin /". Затем я получаю 404, потому что в области «Сайт» нет контроллера администратора.

В обеих областях по умолчанию установлен контроллер "Блог". Я понимаю, что мог бы просто указать site/{controller}/... в качестве URL, но я бы предпочел, чтобы это было в корне, если это возможно. Я также попытался сохранить маршрут по умолчанию в глобальной функции RegisterRoutes, однако затем он не отправляется в область «Сайты».

Заранее спасибо!

Ответы [ 4 ]

30 голосов
/ 21 января 2010

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

protected void Application_Start() {
    var area1reg = new Area1AreaRegistration();
    var area1context = new AreaRegistrationContext(area1reg.AreaName, RouteTable.Routes);
    area1reg.RegisterArea(area1context);

    var area2reg = new Area2AreaRegistration();
    var area2context = new AreaRegistrationContext(area2reg.AreaName, RouteTable.Routes);
    area2reg.RegisterArea(area2context);

    var area3reg = new Area3AreaRegistration();
    var area3context = new AreaRegistrationContext(area3reg.AreaName, RouteTable.Routes);
    area3reg.RegisterArea(area3context);
}

Другой вариант - взять код для RegisterAllAreas (), скопировать его в собственное приложение и создать собственный механизм определения порядка. Это довольно много кода, который нужно скопировать, если вам нужна вся причудливая логика кэширования, которую имеет встроенный метод, но вашему приложению это может даже не понадобиться.

7 голосов
/ 29 октября 2009

В настоящее время невозможно заказать участки. Тем не менее, я думаю, что имеет смысл попытаться сделать каждую область как можно более независимой от других областей, чтобы порядок не имел значения.

Например, вместо использования маршрута по умолчанию {controller} / {action} / {id}, возможно, замените его конкретными маршрутами для каждого контроллера. Или добавьте ограничение к этому маршруту по умолчанию.

Мы обдумываем варианты, чтобы разрешить заказ, но не хотим слишком усложнять функцию.

4 голосов
/ 25 апреля 2012

Для справки,

В MVC3 (не знаю о MVC2), когда вы просто хотите отобразить root на определенную область / контроллер, вы можете просто использовать глобальный маршрут. Просто не забудьте указать пространство имен / область.

    routes.MapRoute(
      "CatchRoot", "",
      new { controller = "SITEBLOG-CONTROLLER-NAME", action = "Index"} 
     ).DataTokens.Add("area", "SITE-AREA-NAME");
4 голосов
/ 21 января 2011

Я делаю это решение:

AreaUtils.cs

    using System;
    using System.Web.Mvc;
    using System.Web.Routing;

    namespace SledgeHammer.Mvc.Site
    {
        public static class Utils
        {
                public static void RegisterArea<T>(RouteCollection routes,
    object state) where T : AreaRegistration

            {
                 AreaRegistration registration =
     (AreaRegistration)Activator.CreateInstance(typeof(T));

                    AreaRegistrationContext context =
     new AreaRegistrationContext(registration.AreaName, routes, state);

                    string tNamespace = registration.GetType().Namespace;
                    if (tNamespace != null)
                {
                    context.Namespaces.Add(tNamespace + ".*");
                }

                registration.RegisterArea(context);
            }
        }

    }

В global.asax:

Utils.RegisterArea<SystemAreaRegistration>(RouteTable.Routes, null);
Utils.RegisterArea<ClientSitesAreaRegistration>(RouteTable.Routes, null);

//AreaRegistration.RegisterAllAreas(); do not dublicate register areas

Нет необходимости вносить изменения в сгенерированный регистрационный код зоны. Я также использую настраиваемую константу в маршрутах для фильтрации маршрутов по типу домена в запросе (системный домен или сайт пользователя).

Это мой регион регистрации в качестве примера:

namespace SledgeHammer.MVC.Site.Areas.System
{
    public class SystemAreaRegistration : AreaRegistration
    {
        public override string AreaName
        {
            get { return "System"; }
        }

        public override void RegisterArea(AreaRegistrationContext context)
        {
            context.MapRoute(
                "System_Feedback",
                "Feedback",
                new { controller = "Feedback", action = "Index" }
            );
            context.MapRoute(
                "System_Information",
                "Information/{action}/{id}",
                new { controller = "Information", action = "Index", id = UrlParameter.Optional }
            );
        }
    }
}



namespace SledgeHammer.MVC.Site.Areas.ClientSites
{
    public class ClientSitesAreaRegistration : AreaRegistration
    {
        public override string AreaName
        {
            get { return "ClientSites"; }
        }

        public override void RegisterArea(AreaRegistrationContext context)
        {
            context.MapRoute(
                "ClientSites_default",
                "{controller}/{action}/{id}",
                new { controller = "Site", action = "Index", id = UrlParameter.Optional },
                new { Host = new SiteInGroups("clients") }
            );
        }
    }
}
...