关于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
文章写的很差,大家可以下载代码研究,不同可以提问问!
题外话 : 一直说要到博客园上写文章,结果还是没能坚持,真恨自己太懒了。这个功能其实已经写好几个月了,一直说要发布出来,结果还是到了现在才发布出来,而且文章还是写得那么乱,而且还写了整个晚上,真是没写作的天赋!不过还是得坚持把一些东西写出来,分享给大家一起进步!