Asp.net mvc ASP.NET MVC子域
我有这样的主机和域名:Asp.net mvc ASP.NET MVC子域,asp.net-mvc,subdomain,Asp.net Mvc,Subdomain,我有这样的主机和域名: www.EXAMPLE.com www.PAGE1.EXAMPLE.com www.PAGE2.EXAMPLE.com www.PAGE3.EXAMPLE.com ... etc... 我已经创建了几个这样的子域: www.EXAMPLE.com www.PAGE1.EXAMPLE.com www.PAGE2.EXAMPLE.com www.PAGE3.EXAMPLE.com ... etc... 所有这些子域都指向同一个ASP.NET MVC 5应用程序 我想做
www.EXAMPLE.com
www.PAGE1.EXAMPLE.com
www.PAGE2.EXAMPLE.com
www.PAGE3.EXAMPLE.com
... etc...
我已经创建了几个这样的子域:
www.EXAMPLE.com
www.PAGE1.EXAMPLE.com
www.PAGE2.EXAMPLE.com
www.PAGE3.EXAMPLE.com
... etc...
所有这些子域都指向同一个ASP.NET MVC 5应用程序
我想做一个系统,它将根据子域加载数据。
例如:
我有文章对象,可以是自动评论、游戏评论或书评等
我想在www.auto.example.com加载文章类型为auto的数据,在www.book.example.com加载书籍类型的数据等
将有许多类型的页面
这样做的最佳实践是什么
顶级域www.example.com应显示其他内容。这将是其他人的主页。您可以通过编写自定义路由来实现这一点。以下是如何(改编自) 以及您的控制器方法:
public ActionResult Index(string subdomain)
{
//Query your database for the relevant articles based on subdomain
var viewmodel = MyRepository.GetArticles(subdomain);
Return View(viewmodel);
}
这是我很久以来一直想用ASP.NET MVC做的事情,但是。。。这不是ASP.NET MVC负责的问题。这是一个服务器问题(IIS)。您需要做的是允许在IIS服务器上使用通配符子域,并将它们指向您的one应用程序 然后您可以使用HttpContext执行类似的操作:
HttpContext.Current.Request.Url.Host // user1.yourwebsite.com
然后,您只需解析它,并将其推送到您的ASP.NET MVC应用程序中,不管您认为合适:
- 把它推到会话中
- 更新当前路线数据并输入值
- 等等
注意:这里的缺点是,这使得本地开发变得越来越困难,因此您可能希望模拟一种方法,在应用程序中伪造子域。我尝试了
Paul Taylor
上面的答案很好,但这对我来说并不完全有效。
我使用Route
类的这个实现
将自定义域添加到C:/Windows/System32/drivers/etc/hosts
文件中
- 127.0.0.1 subdomain.localhost.com
DomainData.cs
public class DomainData
{
public string Protocol { get; set; }
public string HostName { get; set; }
public string Fragment { get; set; }
}
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 && requestDomain.ToLower() != "tg.local" &&
requestDomain.ToLower() != "tg.terrasynq.net" && requestDomain.ToLower() != "www.townsgossip.com" &&
requestDomain.ToLower() != "townsgossip.com")
{
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)
{
var 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;
}
}
DomainRoute.cs
public class DomainData
{
public string Protocol { get; set; }
public string HostName { get; set; }
public string Fragment { get; set; }
}
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 && requestDomain.ToLower() != "tg.local" &&
requestDomain.ToLower() != "tg.terrasynq.net" && requestDomain.ToLower() != "www.townsgossip.com" &&
requestDomain.ToLower() != "townsgossip.com")
{
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)
{
var 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;
}
}
公共类域路由:路由
{
私有Regex域Regex;
私有正则表达式pathRegex;
公共字符串域{get;set;}
公共域路由(字符串域、字符串url、RouteValueDictionary默认值)
:base(url,默认值,新的MvcRouteHandler())
{
域=域;
}
公共域路由(字符串域、字符串url、RouteValueDictionary默认值、IRoutHandler routeHandler)
:base(url、默认值、routeHandler)
{
域=域;
}
公共域路由(字符串域、字符串url、对象默认值)
:base(url、新RouteValueDictionary(默认值)、新MvcRouteHandler())
{
域=域;
}
公共域路由(字符串域、字符串url、对象默认值、IRouteHandler routeHandler)
:base(url、新RouteValueDictionary(默认值)、routeHandler)
{
域=域;
}
公共覆盖路由数据GetRouteData(HttpContextBase httpContext)
{
//构建正则表达式
domainRegex=CreateRegex(域);
pathRegex=CreateRegex(Url);
//请求信息
string requestDomain=httpContext.Request.Headers[“主机”];
如果(!string.IsNullOrEmpty(requestDomain))
{
if(requestDomain.IndexOf(“:”)大于0)
{
requestDomain=requestDomain.Substring(0,requestDomain.IndexOf(“:”);
}
}
其他的
{
requestDomain=httpContext.Request.Url.Host;
}
string requestPath=httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2)+
httpContext.Request.PathInfo;
//匹配域和路由
Match domainMatch=domainRegex.Match(requestDomain);
Match-pathMatch=pathRegex.Match(请求路径);
//路由数据
RoutedData=null;
if(domainMatch.Success&&pathMatch.Success&&requestDomain.ToLower()!=“tg.local”&&
requestDomain.ToLower()!=“tg.terrasynq.net”和&requestDomain.ToLower()!=“www.townsgossip.com”&&
requestDomain.ToLower()!=“townsgossip.com”)
{
数据=新的路由数据(这是RouteHandler);
//首先添加默认值
if(默认值!=null)
{
foreach(默认值中的KeyValuePair项)
{
data.Values[item.Key]=item.Value;
}
}
//迭代匹配域组
对于(int i=1;i