Pregunta

Noté que en MVC 2 Preview 2, AreaRegistration está cargando las rutas para cada área en un orden arbitrario. ¿Hay una buena manera de obtener uno antes que el otro?

Por ejemplo, tengo dos áreas: " Sitio " y "Administrador". Ambos tienen un " Blog " controlador.

Me gustaría lo siguiente:

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

El problema es que primero está cargando la ruta del sitio, por lo que coincide con {controller} / {action} / {id} en lugar de admin / {controller} / {action } / {id} cuando voy a la url " / admin / " ;. Luego obtengo un 404, porque no hay un controlador de administrador en el "Sitio" área.

Ambas áreas tienen por defecto el " Blog " controlador. Me doy cuenta de que podría simplemente poner site / {controller} / ... como la url, pero preferiría tenerlo en la raíz si es posible. También intenté mantener la ruta predeterminada en la función global RegisterRoutes, sin embargo, luego no se envía a los "Sitios". área.

¡Gracias de antemano!

¿Fue útil?

Solución

Actualmente no es posible ordenar áreas. Sin embargo, creo que tiene sentido tratar de hacer que cada área sea lo más independiente posible de otras áreas para que el orden no importe.

Por ejemplo, en lugar de tener la ruta predeterminada {controller} / {action} / {id}, puede reemplazarla con rutas específicas para cada controlador. O agregue una restricción a esa ruta predeterminada.

Estamos reflexionando sobre las opciones para permitir el pedido, pero no queremos complicar demasiado la función.

Otros consejos

Aparte de lo que dijo Haacked, es muy posible ordenar registros de área (y, por lo tanto, sus rutas). Todo lo que tiene que hacer es registrar cada área manualmente, en el orden que desee. No es tan elegante como llamar a RegisterAllAreas () pero definitivamente es factible.

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

Otra opción es tomar el código para RegisterAllAreas (), copiarlo en su propia aplicación y crear su propio mecanismo para determinar el orden. Copiar es un poco de código si desea toda la lógica de almacenamiento en caché elegante que hace el método incorporado, pero es posible que su aplicación ni siquiera lo necesite.

Hago esta solución:

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

    }

En global.asax:

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

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

No se requieren cambios en el código de registro del área generada. También utilizo restricciones personalizadas en rutas para filtrar rutas por tipo de dominio en la solicitud (dominio del sistema o sitio del usuario).

Este es mi registro de área como ejemplo:

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 referencia,

En MVC3 (no sé acerca de MVC2) cuando solo desea asignar la raíz a un área / controlador específico, simplemente puede usar una ruta global. Solo recuerde especificar el espacio de nombres / área.

    routes.MapRoute(
      "CatchRoot", "",
      new { controller = "SITEBLOG-CONTROLLER-NAME", action = "Index"} 
     ).DataTokens.Add("area", "SITE-AREA-NAME");
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top