Question

J'ai remarqué que dans MVC 2 Preview 2, AreaRegistration charge les routes de chaque zone dans un ordre arbitraire. Existe-t-il un bon moyen d’en obtenir un avant l’autre?

Par exemple, j'ai deux zones: "Site". et "Admin". Les deux ont un " Blog " manette.

Je voudrais ce qui suit:

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

Le problème vient du fait qu’il commence par charger la route du site. Elle correspond donc à {contrôleur} / {action} / {id} au lieu de admin / {contrôleur} / {action } / {id} quand je vais à l'URL "/ admin /". J'obtiens alors un 404, car il n'y a pas de contrôleur d'administrateur dans le "Site". région.

Les deux zones sont définies par défaut sur & Blog; Blog " manette. Je réalise que je pourrais simplement mettre site / {controller} / ... en tant qu'url, mais je préférerais que ce soit à la racine si possible. J'ai également essayé de conserver la route par défaut dans la fonction globale RegisterRoutes, mais elle n'est alors pas envoyée aux "Sites". région.

Merci d'avance!

Était-ce utile?

La solution

Actuellement, il n'est pas possible de commander des zones. Cependant, je pense qu'il est logique d'essayer de rendre chaque domaine aussi indépendant que possible des autres domaines afin que l'ordre n'ait pas d'importance.

Par exemple, au lieu d’avoir la route par défaut {controller} / {action} / {id}, remplacez-la par des routes spécifiques pour chaque contrôleur. Ou ajoutez une contrainte à cette route par défaut.

Nous réfléchissons à des options pour autoriser les commandes, mais nous ne voulons pas compliquer la fonctionnalité de manière excessive.

Autres conseils

Hormis ce que Haacked a dit, il est très possible de commander des enregistrements de zone (et donc leurs itinéraires). Tout ce que vous avez à faire est d’enregistrer chaque zone manuellement, dans l’ordre que vous souhaitez. Ce n'est pas aussi élégant que d'appeler RegisterAllAreas () mais c'est tout à fait faisable.

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

Une autre option consiste à prendre le code de RegisterAllAreas (), à le copier dans votre propre application et à créer votre propre mécanisme pour déterminer l'ordre. C’est un peu de code à copier si vous voulez toute la logique de mise en cache sophistiquée de la méthode intégrée, mais votre application n’en aura peut-être même pas besoin.

Je crée cette solution:

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

    }

Dans global.asax:

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

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

Aucune modification nécessaire au code d'enregistrement de zone généré. J’utilise également coutant personnalisé dans les itinéraires pour filtrer les itinéraires par type de domaine demandé (domaine système ou site utilisateur).

Voici les enregistrements de ma région à titre d'exemple:

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

Pour référence,

Dans MVC3 (ne sait pas sur MVC2), lorsque vous souhaitez simplement mapper la racine sur une zone / un contrôleur spécifique, vous pouvez simplement utiliser un itinéraire global. N'oubliez pas de spécifier l'espace de noms / la zone.

    routes.MapRoute(
      "CatchRoot", "",
      new { controller = "SITEBLOG-CONTROLLER-NAME", action = "Index"} 
     ).DataTokens.Add("area", "SITE-AREA-NAME");
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top