MVC 2 AreaRegistration Routes Order

前端 未结 4 2109
日久生厌
日久生厌 2020-12-03 06:00

I noticed that in MVC 2 Preview 2, AreaRegistration is loading the routes for each area in an arbitrary order. Is there a good way to get one before the other?

For e

相关标签:
4条回答
  • 2020-12-03 06:17

    For reference,

    In MVC3 (don't know about MVC2) when you just want to map root to a specific area/controller you could simply use a global route. Just remember to specify the namespace/area.

        routes.MapRoute(
          "CatchRoot", "",
          new { controller = "SITEBLOG-CONTROLLER-NAME", action = "Index"} 
         ).DataTokens.Add("area", "SITE-AREA-NAME");
    
    0 讨论(0)
  • 2020-12-03 06:21

    Aside from what Haacked said, it is very much possible to order area registrations (and thus their routes). All you have to do is register each area manually, in whatever order you want. It's not as sleek as calling RegisterAllAreas() but it's definitely doable.

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

    Another option is to take the code for RegisterAllAreas(), copy it into your own app, and build your own mechanism for determining the order. It is quite a bit of code to copy if you want all the fancy caching logic that the built-in method does, but your app might not even need that.

    0 讨论(0)
  • 2020-12-03 06:30

    I make this 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);
                }
            }
    
        }
    

    In global.asax:

    Utils.RegisterArea<SystemAreaRegistration>(RouteTable.Routes, null);
    Utils.RegisterArea<ClientSitesAreaRegistration>(RouteTable.Routes, null);
    
    //AreaRegistration.RegisterAllAreas(); do not dublicate register areas
    

    No requred changes to generated area registration code. I also use custom constrant in routes to filter routes by type of domain in request (system domain or user site).

    This is my area registrations as example:

    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") }
                );
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-03 06:34

    Currently it's not possible to order areas. However, I think it makes sense to try and make each area as independent from other areas as possible so the order doesn't matter.

    For example, instead of having the default {controller}/{action}/{id} route, maybe replace that with specific routes for each controller. Or add a constraint to that default route.

    We are mulling over options to allow ordering, but we don't want to overcomplicate the feature.

    0 讨论(0)
提交回复
热议问题