環境說明 項目採用mvc4,有個area,名稱為 demo,訪問路徑 http://localhost:8098/demo,需要把demo.abc.com 映射到改路徑 hosts 配置 127.0.0.1 demo.abc.com 核心代碼 調用代碼 視圖使用 bool b = (string)V ...
環境說明
項目採用mvc4,有個area,名稱為 demo,訪問路徑 http://localhost:8098/demo,需要把demo.abc.com 映射到改路徑
hosts 配置
127.0.0.1 demo.abc.com
核心代碼
public class AreaDomainRegistrationContext { /// <summary> /// /// </summary> /// <param name="_domainName">子功能變數名稱 如:www.xxx.com 可以傳 abc</param> public AreaDomainRegistrationContext(AreaRegistrationContext _context, string _domainName) { domainName = _domainName; context = _context; } private string domainName; private AreaRegistrationContext context; private RouteCollection Routes { get { if (!DomainRouteTable.DomainRoutes.ContainsKey(domainName)) { DomainRouteTable.DomainRoutes[domainName] = new RouteCollection(); } return DomainRouteTable.DomainRoutes[domainName]; } } public Route MapRoute(string name, string url, object defaults, object constraints = null, string[] namespaces = null) { if (namespaces == null && context.Namespaces != null) { namespaces = context.Namespaces.ToArray(); } Route route = Routes.MapRoute(name, url, defaults, constraints, namespaces); route.DataTokens["area"] = context.AreaName; route.DataTokens["UseNamespaceFallback"] = false; route.DataTokens["SubDomain"] = domainName; return route; } } public class DomainRouteTable { private static Dictionary<string, RouteCollection> _instance = new Dictionary<string, RouteCollection>(); public static Dictionary<string, RouteCollection> DomainRoutes { get { return _instance; } } } public class DomainRoute : RouteBase { public ResolveDomainName resolveDomainName = DependencyResolver.Current.GetService<ResolveDomainName>(); public RouteData d = new RouteData(null, new StopRoutingHandler()); public override RouteData GetRouteData(HttpContextBase httpContext) { string domainName = resolveDomainName.Resolve(httpContext); //該主機頭沒有配置,返回 null 繼續查找路由 if (domainName == null) return null; if (!DomainRouteTable.DomainRoutes.ContainsKey(domainName)) return d; var rs = DomainRouteTable.DomainRoutes[domainName]; RouteData routeData = rs.GetRouteData(httpContext); if (routeData == null) return d; return routeData; } public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) { string domainName = resolveDomainName.Resolve(requestContext.HttpContext); if (domainName == null) return null; if (!DomainRouteTable.DomainRoutes.ContainsKey(domainName)) return null; var rs = DomainRouteTable.DomainRoutes[domainName]; VirtualPathData vpd = rs.GetVirtualPathForArea(requestContext, values); return vpd; } } public class ResolveDomainName { public static Dictionary<string, string> DomainMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); public string Resolve(HttpContextBase httpContext) { string key = httpContext.Request.Headers["host"]; string value; if (DomainMap.TryGetValue(key, out value)) { return value; } else return null; } }
調用代碼
//Global.asax.cs 的 Application_Start 放在最前面 RouteTable.Routes.Add(new DomainRoute()); ResolveDomainName.DomainMap.Add("demo.abc.com:8098", "demo"); // Area demo 的路由註冊 public class demoAreaRegistration : AreaRegistration { public override string AreaName { get { return "demo"; } } public override void RegisterArea(AreaRegistrationContext context) { context.MapRoute( name: "demo_default", url: "demo/{controller}/{action}", defaults: new { controller = "index", action = "index" }, namespaces: new string[] { "xxx.xxx" }); var context2 = new AreaDomainRegistrationContext(context, "demo"); context2.MapRoute( name: "demo_default", url: "{controller}/{action}", defaults: new { controller = "index", action = "index" }, namespaces: new string[] { "xxx.xxx" }); } }
視圖使用 bool b = (string)ViewContext.RouteData.DataTokens["SubDomain"] != null; 可以判斷請求是否使用demo.abc.com功能變數名稱訪問
使用 http://demo.abc.com:8098/ 和 http://localhost:8098/demo 都可以訪問Area demo