Domanda

Ho notato che in MVC 2 Preview 2, AreaRegistration sta caricando i percorsi per ciascuna area in un ordine arbitrario. C'è un buon modo per ottenerne uno prima dell'altro?

Ad esempio, ho due aree - " Sito " e " Admin " ;. Entrambi hanno un " Blog " controller.

Vorrei quanto segue:

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

Il problema è che sta caricando prima il percorso del sito, quindi corrisponde a {controller} / {action} / {id} anziché admin / {controller} / {action } / {id} quando vado all'URL " / admin / " ;. Ricevo quindi un 404, perché non esiste un controller di amministrazione nel "Sito" zona.

Entrambe le aree impostano per impostazione predefinita il " Blog " controller. Mi rendo conto che potrei semplicemente mettere site / {controller} / ... come url, ma preferirei averlo alla radice, se possibile. Ho anche provato a mantenere il percorso predefinito nella funzione globale RegisterRoutes, tuttavia, non viene quindi inviato ai "Siti" zona.

Grazie in anticipo!

È stato utile?

Soluzione

Attualmente non è possibile ordinare aree. Tuttavia, penso che abbia senso cercare di rendere ogni area il più indipendente possibile da altre aree, quindi l'ordine non ha importanza.

Ad esempio, invece di avere la route predefinita {controller} / {action} / {id}, è possibile sostituirla con route specifiche per ciascun controller. Oppure aggiungi un vincolo a quella route predefinita.

Stiamo riflettendo sulle opzioni per consentire l'ordinamento, ma non vogliamo complicare eccessivamente la funzione.

Altri suggerimenti

A parte quanto detto da Haacked, è molto possibile ordinare le registrazioni di area (e quindi i loro percorsi). Tutto quello che devi fare è registrare manualmente ciascuna area, nell'ordine che desideri. Non è elegante come chiamare RegisterAllAreas () ma è sicuramente fattibile.

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

Un'altra opzione è prendere il codice per RegisterAllAreas (), copiarlo nella propria app e creare il proprio meccanismo per determinare l'ordine. È abbastanza un po 'di codice da copiare se vuoi tutta la logica di cache di fantasia che il metodo integrato fa, ma la tua app potrebbe non averne nemmeno bisogno.

Faccio questa soluzione:

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

    }

In global.asax:

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

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

Nessuna modifica richiesta al codice di registrazione dell'area generato. Uso anche il costruttore personalizzato nelle route per filtrare le route in base al tipo di dominio richiesto (dominio di sistema o sito utente).

Questa è la mia area di registrazione come esempio:

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

Per riferimento,

In MVC3 (non si conosce MVC2) quando si desidera solo mappare il root su un'area / controller specifici, è possibile semplicemente utilizzare una route globale. Ricorda solo di specificare lo spazio dei nomi / l'area.

    routes.MapRoute(
      "CatchRoot", "",
      new { controller = "SITEBLOG-CONTROLLER-NAME", action = "Index"} 
     ).DataTokens.Add("area", "SITE-AREA-NAME");
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top