用Asp.Net MVC实现泛域名解析
实现了如下功能:
www.{language}-{culture}.example.com
www.{controller}.example.com/{action}
www.{clientname}.example.com
routes.Add("DomainRoute", new DomainRoute(
"home.example.com", // Domain with parameters
"{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
));
//routes.Add("DomainRoute", new DomainRoute(
// "{controller}.example.com", // Domain with parameters
// "{action}/{id}", // URL with parameters
// new { controller = "Home", action = "Index", id = "" } // Parameter defaults
//));
//routes.Add("DomainRoute", new DomainRoute(
// "{controller}-{action}.example.com", // Domain with parameters
// "{id}", // URL with parameters
// new { controller = "Home", action = "Index", id = "" } // Parameter defaults
//));
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
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)
{
// Build regex
domainRegex = CreateRegex(Domain);
pathRegex = CreateRegex(Url);
// Request information
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 domain and route
Match domainMatch = domainRegex.Match(requestDomain);
Match pathMatch = pathRegex.Match(requestPath);
// Route data
RouteData data = null;
if (domainMatch.Success && pathMatch.Success)
{
data = new RouteData(this, RouteHandler);
// Add defaults first
if (Defaults != null)
{
foreach (KeyValuePair<string, object> item in Defaults)
{
data.Values[item.Key] = item.Value;
}
}
// Iterate matching domain groups
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;
}
}
}
}
// Iterate matching path groups
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;
}
}
}
}
}
return data;
}
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
return base.GetVirtualPath(requestContext, RemoveDomainTokens(values));
}
public DomainData GetDomainData(RequestContext requestContext, RouteValueDictionary values)
{
// Build hostname
string hostname = Domain;
foreach (KeyValuePair<string, object> pair in values)
{
hostname = hostname.Replace("{" pair.Key "}", pair.Value.ToString());
}
// Return domain data
return new DomainData
{
Protocol = "http",
HostName = hostname,
Fragment = ""
};
}
private Regex CreateRegex(string source)
{
// Perform replacements
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;
}
}
资源文件列表
MvcDomainRouting/MvcDomainRouting/Code/DomainData.cs , 314
MvcDomainRouting/MvcDomainRouting/Code/DomainRoute.cs , 6421
MvcDomainRouting/MvcDomainRouting/Code/LinkExtensions.cs , 3883
MvcDomainRouting/MvcDomainRouting/Content/Site.css , 4952
MvcDomainRouting/MvcDomainRouting/Controllers/AccountController.cs , 13054
MvcDomainRouting/MvcDomainRouting/Controllers/HomeController.cs , 482
MvcDomainRouting/MvcDomainRouting/Default.aspx , 269
MvcDomainRouting/MvcDomainRouting/Default.aspx.cs , 826
MvcDomainRouting/MvcDomainRouting/Global.asax , 108
MvcDomainRouting/MvcDomainRouting/Global.asax.cs , 2132
MvcDomainRouting/MvcDomainRouting/MvcDomainRouting.csproj , 6049
MvcDomainRouting/MvcDomainRouting/MvcDomainRouting.csproj.user , 1360
MvcDomainRouting/MvcDomainRouting/Properties/AssemblyInfo.cs , 1459
MvcDomainRouting/MvcDomainRouting/Scripts/jquery-1.3.2-vsdoc.js , 202542
MvcDomainRouting/MvcDomainRouting/Scripts/jquery-1.3.2.js , 127052
MvcDomainRouting/MvcDomainRouting/Scripts/jquery-1.3.2.min-vsdoc.js , 202542
MvcDomainRouting/MvcDomainRouting/Scripts/jquery-1.3.2.min.js , 59326
MvcDomainRouting/MvcDomainRouting/Scripts/MicrosoftAjax.debug.js , 310836
MvcDomainRouting/MvcDomainRouting/Scripts/MicrosoftAjax.js , 99358
MvcDomainRouting/MvcDomainRouting/Scripts/MicrosoftMvcAjax.debug.js , 12592
MvcDomainRouting/MvcDomainRouting/Scripts/MicrosoftMvcAjax.js , 4870
MvcDomainRouting/MvcDomainRouting/Views/Account/ChangePassword.aspx , 1742
MvcDomainRouting/MvcDomainRouting/Views/Account/ChangePasswordSuccess.aspx , 453
MvcDomainRouting/MvcDomainRouting/Views/Account/LogOn.aspx , 1482
MvcDomainRouting/MvcDomainRouting/Views/Account/Register.aspx , 1880
MvcDomainRouting/MvcDomainRouting/Views/Home/About.aspx , 390
MvcDomainRouting/MvcDomainRouting/Views/Home/Index.aspx , 526
MvcDomainRouting/MvcDomainRouting/Views/Shared/Error.aspx , 439
MvcDomainRouting/MvcDomainRouting/Views/Shared/LogOnUserControl.ascx , 375
MvcDomainRouting/MvcDomainRouting/Views/Shared/Site.Master , 1262
MvcDomainRouting/MvcDomainRouting/Views/Web.config , 1568
MvcDomainRouting/MvcDomainRouting/Web.config , 11120
MvcDomainRouting/MvcDomainRouting.sln , 938
MvcDomainRouting/MvcDomainRouting.suo , 45568
