mvc 实现不同的域 绑定不同的域名
首先是定义routes:
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.Add("DomainRouteForManage", new DomainRoute( "1510x68z34.51mypc.cn", // 固定的主域名 "{controller}/{action}/{id}", // URL with parameters new { area = "Admin", controller = "Home", action = "Index", id = "", Namespaces = new string[] { "XR_WeChatManagement.Web.Areas.Admin.Controllers" } } // Parameter defaults )); routes.Add("DomainRouteForge", new DomainRoute( "www.1510x68z34.51mypc.cn", // www也是固定的主域名需要过滤 "{controller}/{action}/{id}", // URL with parameters new { area = "Admin", controller = "Home", action = "Index", id = "", Namespaces = new string[] { "XR_WeChatManagement.Web.Areas.Admin.Controllers" } } // Parameter defaults )); routes.Add("DomainRoute", new DomainRoute( "{weChatName}.1510x68z34.51mypc.cn", // 固定的三级域名(微网站用) "{controller}/{action}/{id}", // URL with parameters new { area = "WebSite", controller = "Home", action = "Index", id = "", Namespaces = new string[] { "XR_WeChatManagement.Web.Areas.WebSite.Controllers" } } // Parameter defaults )); routes.MapRoute( "Default", // 路由名称 "WebSite/{controller}/{action}/{id}", // 带有参数的 URL new { area = "WebSite", controller = "Home", action = "Index", id = UrlParameter.Optional }, null, new string[] { "XR_WeChatManagement.Web.Areas.WebSite.Controllers" } // 参数默认值 ); }
肯定会有错的,然后再App_Start目录下新建两个类:
1.DomainRoute.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using System.Web; using System.Web.Mvc; using System.Web.Routing; namespace XR_WeChatManagement.Web.App_Start { public class DomainRoute : Route { private Regex domainRegex; private Regex pathRegex; public string Domain { get; set; } public DomainRoute(string domain, string url, RouteValueDictionary defaults) : base(url, defaults, new MvcRouteHandler()) { Domain = domain; } public DomainRoute(string domain, string url, RouteValueDictionary defaults, IRouteHandler routeHandler) : base(url, defaults, routeHandler) { Domain = domain; } public DomainRoute(string domain, string url, object defaults) : base(url, new RouteValueDictionary(defaults), new MvcRouteHandler()) { Domain = domain; } public DomainRoute(string domain, string url, object defaults, IRouteHandler routeHandler) : base(url, new RouteValueDictionary(defaults), routeHandler) { Domain = domain; } public override RouteData GetRouteData(HttpContextBase httpContext) { // 构造 regex domainRegex = CreateRegex(Domain); pathRegex = CreateRegex(Url); // 请求信息 string requestDomain = httpContext.Request.Headers["host"]; if (!string.IsNullOrEmpty(requestDomain)) { if (requestDomain.IndexOf(":") > 0) { requestDomain = requestDomain.Substring(0, requestDomain.IndexOf(":")); } } else { requestDomain = httpContext.Request.Url.Host; } string requestPath = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2) + httpContext.Request.PathInfo; // 匹配域名和路由 Match domainMatch = domainRegex.Match(requestDomain); Match pathMatch = pathRegex.Match(requestPath); // 路由数据 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; } public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) { return base.GetVirtualPath(requestContext, RemoveDomainTokens(values)); } public DomainData GetDomainData(RequestContext requestContext, RouteValueDictionary values) { // 获得主机名 string hostname = Domain; foreach (KeyValuePair<string, object> pair in values) { hostname = hostname.Replace("{" + pair.Key + "}", pair.Value.ToString()); } // Return 域名数据 return new DomainData { Protocol = "http", HostName = hostname, Fragment = "" }; } private Regex CreateRegex(string source) { // 替换 source = source.Replace("/", @"\/?"); source = source.Replace(".", @"\.?"); source = source.Replace("-", @"\-?"); source = source.Replace("{", @"(?<"); source = source.Replace("}", @">([a-zA-Z0-9_]*))"); return new Regex("^" + source + "$"); } private RouteValueDictionary RemoveDomainTokens(RouteValueDictionary values) { Regex tokenRegex = new Regex(@"({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?"); Match tokenMatch = tokenRegex.Match(Domain); for (int i = 0; i < tokenMatch.Groups.Count; i++) { Group group = tokenMatch.Groups[i]; if (group.Success) { string key = group.Value.Replace("{", "").Replace("}", ""); if (values.ContainsKey(key)) values.Remove(key); } } return values; } } }
2.DomainData.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace XR_WeChatManagement.Web.App_Start { public class DomainData { public string Protocol { get; set; } public string HostName { get; set; } public string Fragment { get; set; } } }