jobily

摆弄着自己的代码,尽全力可能做到最好!无法样样精通,那么就将某个方面做到极致!
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

ASP.NET MVC 使用二级域名来注册Area区域

Posted on 2011-10-09 22:10  jobily  阅读(8926)  评论(27编辑  收藏  举报

     关于ASP.NET MVC 实现二级域名,已有讲解,请见博客园:http://www.cnblogs.com/luanwey/archive/2009/08/12/1544444.html

     现在我要说的是怎么用routing engine (System.Web.Routing) 来自动注册区域以实现多个Views。如一个做区域性的网站,像58、赶集网等,每个城市都分站,而每个城市的城市的页面大致相同,只是根据每个城市去取数据!现在我们要完成一种功能,如网址:cs.8fdc.com 则加载的是长沙的视图,而sz.8fdc.com 则加载的是深圳的视图。而每个城市的视图在结构位置上可能不同,所以又要可以单独去写该城市的视图。

    所以我们要的功能则是:cs.8fdc.com 应该是要匹配到 {area}.8fdc.com  这个路上滴! 如图 :我们要匹配到 Areas上的 cd或者 cs文件夹下的视图。

关于 注册 Areas里的视图,微软为我们提供了一种方法:

 public class AreaRouting : AreaRegistration
    {
        public override string AreaName
        {
            get { return "cs"; }
        }

        public override void RegisterArea(AreaRegistrationContext context)
        {
            context.MapRoute(
                "Default1", // 路由名称
                "cs/{controller}/{action}/{id}", // 带有参数的 URL
                new
                {
                    action = "Index",
                    id = UrlParameter.Optional
                },
                null,
                new string[] { "HB.Controllers.WebSite" } // 选择命名空间,此为HB.Controllers.WebSite的命名空间
                );
        }

        public static void RegisterRoutes(RouteCollection routes)
        {
            //routes.IgnoreRoute("{resource}.axd/{*pathInfo}");       
           
        }
    }

  继承 AreaRegistration ,重写方法则可注册区域,当我们使用 http://localhost/cs/..., 则会注册区域为cs,并匹配到该路由。

     但是我们要的是 http://cs.8fdc.com/...这种 ,也就是我们要使用 http://{area}.8fdc.com 这种方式,根据 ASP.NET MVC 实现二级域名 这篇文章 我们可以这样做 

routes.Add("DomainRoute", new DomainRoute( 
    "{area}.8fdc.com",     // Domain with parameters< br />   
    "{controller}/{action}/{id}",    // URL with parameters
    new { controller = "Home", action = "Index", id = "" },  // Parameter defaults
    null,
    new string[] { "HB.Controllers.WebSite" }
));

  但实际上是无法去注册区域的,我们只有将Route Data中的area写入了,并没有将 Data Tokens的 area。可使用 RouteDebug.dll 观察路由信息即可知!所以我们需修改 DomainRoute方法!在DomainRoute.cs 类里修改此处

            // 路由数据
            RouteData data = null;
            if (domainMatch.Success && pathMatch.Success)
            {
                data = new RouteData(this, RouteHandler);
                
                // 添加默认选项
                if (Defaults != null)
                {
                    foreach (KeyValuePair<string, object> item in Defaults)
                    {
                        data.Values[item.Key] = item.Value;
                        #region 此处将area及Namespaces写入DataTokens里
                        if (item.Key.Equals("area") || item.Key.Equals("Namespaces"))
                        {
                            data.DataTokens[item.Key]=item.Value;
                        }
                        #endregion
                    }
                }

                // 匹配域名路由
                for (int i = 1; i < domainMatch.Groups.Count; i++)
                {
                    Group group = domainMatch.Groups[i];
                    if (group.Success)
                    {
                        string key = domainRegex.GroupNameFromNumber(i);

                        if (!string.IsNullOrEmpty(key) && !char.IsNumber(key, 0))
                        {
                            if (!string.IsNullOrEmpty(group.Value))
                            {
                                data.Values[key] = group.Value;
                                #region 新增将area写入到DataTokens中
                                if (key.Equals("area"))
                                {
                                    data.DataTokens[key]=group.Value;
                                }
                                #endregion
                            }
                        }
                    }
                }

                // 匹配域名路径
                for (int i = 1; i < pathMatch.Groups.Count; i++)
                {
                    Group group = pathMatch.Groups[i];
                    if (group.Success)
                    {
                        string key = pathRegex.GroupNameFromNumber(i);

                        if (!string.IsNullOrEmpty(key) && !char.IsNumber(key, 0))
                        {
                            if (!string.IsNullOrEmpty(group.Value))
                            {
                                data.Values[key] = group.Value;
                                #region 新增将area写入到DataTokens中
                                if (key.Equals("area"))
                                {
                                    data.DataTokens[key]= group.Value;
                                }
                                #endregion
                            }
                        }
                    }
                }
            }

            return data;

然后在 Global.asax 加入

public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.Add("DomainRouteForManage", new DomainRoute(
                "manage.8fdc.com",                             // 固定的二级域名
                "{controller}/{action}/{id}",                  // URL with parameters
                new
                {
                    area = "Manage",
                    controller = "Home",
                    action = "Index",
                    id = "",
                    Namespaces = new string[] { "HB.Controllers.Manage" }
                }  // Parameter defaults
            ));

            routes.Add("DomainRouteForMutiWebSite", new DomainRoute(
                "{area}.8fdc.com",                             // {area}作为二级域名
                "{controller}/{action}/{id}",                  // URL with parameters
                new
                {
                    area = "cs",
                    controller = "Home",
                    action = "Index",
                    id = "",
                    Namespaces = new string[] { "HB.Controllers.WebSite" }
                }  // Parameter defaults
            ));

            routes.MapRoute(
                "Default", // 路由名称
                "{area}/{controller}/{action}/{id}", // 带有参数的 URL
                new
                {
                    area = "cs",                    
                    controller = "Home",
                    action = "Index",
                    id = UrlParameter.Optional
                },
                null,
                new string[] { "HB.Controllers.WebSite" } // 参数默认值
              );

           
        }

 第一个 routes.Add 是使用固定的二级域名去 注册区域 ,如图:  

   第二个routes.Add则是使用 {area}作为二级域名。

  

    最后routes.MapRoute 则是默认的路由方法 ,没有注册区域的功能,直接使用根目录下默认的Views里的视图

此方法则可以实现 多个区域使用同一个控制器,而且不要重写AreaRegistration里的方法,可实现根据area的名称来动态注册区域,如果我们增加城市站点的话,只要复制Areas里的cs文件夹之类的就可以了!

项目源代码 :http://download.csdn.net/detail/jobily/3668911

发布在csdn上,因为csdn上的号没分了,希望大家帮我加加分!

再附上一个51cto的链接 :http://down.51cto.com/data/262527

文章写的很差,大家可以下载代码研究,不同可以提问问!  

题外话 : 一直说要到博客园上写文章,结果还是没能坚持,真恨自己太懒了。这个功能其实已经写好几个月了,一直说要发布出来,结果还是到了现在才发布出来,而且文章还是写得那么乱,而且还写了整个晚上,真是没写作的天赋!不过还是得坚持把一些东西写出来,分享给大家一起进步!