代码之家  ›  专栏  ›  技术社区  ›  Jason

MVC 2区域注册路线订单

  •  12
  • Jason  · 技术社区  · 17 年前

    我注意到在MVC2预览2中,AreaRegistration以任意顺序加载每个区域的路由。有没有一个好方法可以先得到一个?

    我希望:

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

    {controller}/{action}/{id} 而不是 admin/{controller}/{action}/{id} 当我转到url“/admin/”时。然后我得到一个404,因为在“站点”区域没有管理员控制器。

    这两个区域都默认为“Blog”控制器。我意识到我可以简单地 site/{controller}/... 作为url,但如果可能的话,我宁愿将其放在根目录下。我还尝试在全局RegisterRoutes函数中保留默认路由,但是,它不会发送到“站点”区域。

    提前谢谢!

    4 回复  |  直到 17 年前
        1
  •  30
  •   Eilon    16 年前

    除了Haacked所说的,订购地区注册(以及他们的路线)是非常可能的。你所要做的就是手动注册每个区域,按你想要的顺序。它不像调用RegisterAllAreas()那样流畅,但绝对是可行的。

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

    另一种选择是获取RegisterAllAreas()的代码,将其复制到您自己的应用程序中,并构建您自己的机制来确定顺序。如果您需要内置方法所具有的所有奇特的缓存逻辑,那么要复制的代码就相当多,但您的应用程序可能甚至不需要这些。

        2
  •  7
  •   Haacked    17 年前

    目前无法订购区域。然而,我认为尝试使每个区域尽可能独立于其他区域是有意义的,这样顺序就不重要了。

    例如,不必使用默认的{controller}/{action}/{id}路由,可以使用每个控制器的特定路由替换该路由。或向该默认管线添加约束。

    我们正在考虑允许订购的选项,但我们不想使功能过于复杂。

        3
  •  4
  •   Kuvalda.Spb.Ru    15 年前

    我提出这个解决方案:

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

    在global.asax中:

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

    生成的区域注册码无需更改。 我还使用路由中的自定义constrant按请求中的域类型(系统域或用户站点)过滤路由。

    以下是我的区域注册示例:

    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") }
                );
            }
        }
    }
    
        4
  •  4
  •   Simon    14 年前

    在MVC3(不知道MVC2)中,当您只想将根映射到特定的区域/控制器时,您只需使用全局路由即可。 请记住指定名称空间/区域。

        routes.MapRoute(
          "CatchRoot", "",
          new { controller = "SITEBLOG-CONTROLLER-NAME", action = "Index"} 
         ).DataTokens.Add("area", "SITE-AREA-NAME");
    
    推荐文章