Pergunta

Notei que no MVC 2 Preview 2, AreaRegistration está a carregar as rotas para cada área em uma ordem arbitrária. Existe uma boa maneira de obter um antes do outro?

Por exemplo, tenho duas áreas - "Site" e "Admin". Ambos têm um controlador de "Blog".

Eu gostaria o seguinte:

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

O problema é que ele está carregando a rota do site em primeiro lugar, por isso está combinando {controller}/{action}/{id} vez de admin/{controller}/{action}/{id} quando eu ir para a url "/ admin /". Eu, então, chegar a 404, porque não há nenhum controlador de administração na área de "Site".

Ambas as áreas padrão para o controlador "Blog". Eu percebo que eu poderia simplesmente colocar site/{controller}/... como o url, mas eu preferia tê-lo na raiz, se possível. Eu também tentei manter a rota padrão na função RegisterRoutes global, no entanto, não é então enviada para a área de "Sites".

Agradecemos antecipadamente!

Foi útil?

Solução

No momento não é possível a áreas ordem. No entanto, eu acho que faz sentido para tentar fazer com que cada área, independente de outras áreas como possível, de modo a ordem não importa.

Por exemplo, em vez de ter o / {ação} / {id} rota {controller} padrão, talvez substituir aquele com rotas específicas para cada controlador. Ou adicionar uma restrição a essa rota padrão.

Estamos refletindo sobre opções para permitir a encomenda, mas nós não queremos complicar o recurso.

Outras dicas

Além do que Haacked disse, é muito possível inscrições área fim (e, portanto, suas rotas). Tudo que você tem a fazer é registrar cada área manualmente, em qualquer ordem desejada. Não é tão elegante como chamar RegisterAllAreas () mas é definitivamente factível.

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);
}

Outra opção é levar o código para RegisterAllAreas (), copiá-lo em seu próprio aplicativo, e construir o seu próprio mecanismo para determinar a ordem. É um pouco de código para copiar se você quiser toda a lógica a fantasia de cache que o built-in método faz, mas sua aplicação pode até não precisa disso.

Eu faço esta solução:

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);
            }
        }

    }

No global.asax:

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

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

No requred alterações ao código de registo área gerado. Eu também uso constrant personalizada em rotas para rotas de filtro por tipo de domínio na solicitação (domínio de sistema ou de usuário do site).

Este é o meu inscrições área como exemplo:

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") }
            );
        }
    }
}

Para referência,

Em MVC3 (não sei sobre MVC2) quando você apenas deseja mapear raiz para uma área específica / controlador você poderia simplesmente usar uma rota global. Apenas lembre-se de especificar o namespace / área.

    routes.MapRoute(
      "CatchRoot", "",
      new { controller = "SITEBLOG-CONTROLLER-NAME", action = "Index"} 
     ).DataTokens.Add("area", "SITE-AREA-NAME");
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top