1 public class DomainRoute : Route 2 { 3 private Regex domainRegex; 4 private Regex pathRegex; 5 6 public string Domain { get; set; } 7 8 public DomainRoute(string domain, string url, RouteValueDictionary defaults) 9 : base(url, defaults, new MvcRouteHandler()) 10 { 11 Domain = domain; 12 } 13 14 public DomainRoute(string domain, string url, RouteValueDictionary defaults, IRouteHandler routeHandler) 15 : base(url, defaults, routeHandler) 16 { 17 Domain = domain; 18 } 19 20 public DomainRoute(string domain, string url, object defaults) 21 : base(url, new RouteValueDictionary(defaults), new MvcRouteHandler()) 22 { 23 Domain = domain; 24 } 25 26 public DomainRoute(string domain, string url, object defaults, IRouteHandler routeHandler) 27 : base(url, new RouteValueDictionary(defaults), routeHandler) 28 { 29 Domain = domain; 30 } 31 32 public override RouteData GetRouteData(HttpContextBase httpContext) 33 { 34 // Build regex 35 domainRegex = CreateRegex(Domain); 36 pathRegex = CreateRegex(Url); 37 38 // Request information 39 string requestDomain = httpContext.Request.Headers["host"]; 40 if (!string.IsNullOrEmpty(requestDomain)) 41 { 42 if (requestDomain.IndexOf(":") > 0) 43 { 44 requestDomain = requestDomain.Substring(0, requestDomain.IndexOf(":")); 45 } 46 } 47 else 48 { 49 requestDomain = httpContext.Request.Url.Host; 50 } 51 string requestPath = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2) httpContext.Request.PathInfo; 52 53 // Match domain and route 54 Match domainMatch = domainRegex.Match(requestDomain); 55 Match pathMatch = pathRegex.Match(requestPath); 56 57 // Route data 58 RouteData data = null; 59 if (domainMatch.Success && pathMatch.Success) 60 { 61 data = new RouteData(this, RouteHandler); 62 63 // Add defaults first 64 if (Defaults != null) 65 { 66 foreach (KeyValuePair<string, object> item in Defaults) 67 { 68 data.Values[item.Key] = item.Value; 69 } 70 } 71 72 // Iterate matching domain groups 73 for (int i = 1; i < domainMatch.Groups.Count; i ) 74 { 75 Group group = domainMatch.Groups[i]; 76 if (group.Success) 77 { 78 string key = domainRegex.GroupNameFromNumber(i); 79 80 if (!string.IsNullOrEmpty(key) && !char.IsNumber(key, 0)) 81 { 82 if (!string.IsNullOrEmpty(group.Value)) 83 { 84 data.Values[key] = group.Value; 85 } 86 } 87 } 88 } 89 90 // Iterate matching path groups 91 for (int i = 1; i < pathMatch.Groups.Count; i ) 92 { 93 Group group = pathMatch.Groups[i]; 94 if (group.Success) 95 { 96 string key = pathRegex.GroupNameFromNumber(i); 97 98 if (!string.IsNullOrEmpty(key) && !char.IsNumber(key, 0)) 99 { 100 if (!string.IsNullOrEmpty(group.Value)) 101 { 102 data.Values[key] = group.Value; 103 } 104 } 105 } 106 } 107 } 108 109 return data; 110 } 111 112 public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) 113 { 114 return base.GetVirtualPath(requestContext, RemoveDomainTokens(values)); 115 } 116 117 public DomainData GetDomainData(RequestContext requestContext, RouteValueDictionary values) 118 { 119 // Build hostname 120 string hostname = Domain; 121 foreach (KeyValuePair<string, object> pair in values) 122 { 123 hostname = hostname.Replace("{" pair.Key "}", pair.Value.ToString()); 124 } 125 126 // Return domain data 127 return new DomainData 128 { 129 Protocol = "http", 130 HostName = hostname, 131 Fragment = "" 132 }; 133 } 134 135 private Regex CreateRegex(string source) 136 { 137 // Perform replacements 138 source = source.Replace("/", @"\/?"); 139 source = source.Replace(".", @"\.?"); 140 source = source.Replace("-", @"\-?"); 141 source = source.Replace("{", @"(?<"); 142 source = source.Replace("}", @">([a-zA-Z0-9_]*))"); 143 144 return new Regex("^" source "$"); 145 } 146 147 private RouteValueDictionary RemoveDomainTokens(RouteValueDictionary values) 148 { 149 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_]*})*-?\.?\/?"); 150 Match tokenMatch = tokenRegex.Match(Domain); 151 for (int i = 0; i < tokenMatch.Groups.Count; i ) 152 { 153 Group group = tokenMatch.Groups[i]; 154 if (group.Success) 155 { 156 string key = group.Value.Replace("{", "").Replace("}", ""); 157 if (values.ContainsKey(key)) 158 values.Remove(key); 159 } 160 } 161 162 return values; 163 } 164 }
routes.Add(
"DomainRoute"
,
new
DomainRoute(
"home.example.com"
,
// Domain with parameters
"{action}/{id}"
,
// URL with parameters
new
{ controller =
"Home"
, action =
"Index"
, id =
""
}
// Parameter defaults
));
时间: 2024-10-11 06:30:06