域间路由的MVC5 [英] Domain Routing in MVC5
问题描述
我知道有这些帮助我对类似的事情了几篇文章,但没有。
我有指向同一个应用程序的多个域的单一Web应用程序。我想知道我怎么能基于正试图访问Web应用程序域的路由映射到一个特定的控制器。
我试过目前是没有成功以下。
routes.MapRoute(
名称:WowPoetry
网址:wowpoetry.org/{action}/{id},
默认:新{控制器=哗,行动=索引,ID = UrlParameter.Optional}
);
我结束了下面这个教程要达到什么我想和异常的我用来做域内路由,而不是子域的路由。
实施
routes.Add(新DomainRoute(wowpoetry.org,,新{控制器=哗,行动=索引}));
DomainData.cs
公共类DomainData
{
公共字符串协议{搞定;组; }
公共字符串主机名{获得;组; }
公共字符串片段{搞定;组; }
}
DomainRoute.cs
公共类DomainRoute:路线
{
私人正则表达式domainRegex;
私人正则表达式pathRegex; 公共字符串域{搞定;组; } 公共DomainRoute(字符串域名,URL字符串,RouteValueDictionary默认)
:基地(URL,默认,新MvcRouteHandler())
{
域=域名;
} 公共DomainRoute(字符串域名,URL字符串,RouteValueDictionary违约,IRouteHandler routeHandler)
:基地(URL,默认,routeHandler)
{
域=域名;
} 公共DomainRoute(字符串域名,URL字符串,对象的默认值)
:基地(网址,新RouteValueDictionary(默认),新MvcRouteHandler())
{
域=域名;
} 公共DomainRoute(字符串域名,URL字符串,对象违约,IRouteHandler routeHandler)
:基地(网址,新RouteValueDictionary(默认),routeHandler)
{
域=域名;
} 公众覆盖的RouteData GetRouteData(HttpContextBase的HttpContext)
{
//建立正则表达式
domainRegex = CreateRegex(域);
pathRegex = CreateRegex(URL); //请求信息
字符串requestDomain = httpContext.Request.Headers [主机];
如果(!string.IsNullOrEmpty(requestDomain))
{
如果(requestDomain.IndexOf(:)大于0)
{
requestDomain = requestDomain.Substring(0,requestDomain.IndexOf(:));
}
}
其他
{
requestDomain = httpContext.Request.Url.Host;
}
串requestPath = httpContext.Request.Ap prelativeCurrentExecutionFilePath.Substring(2)+
httpContext.Request.PathInfo; //匹配域和路线
比赛domainMatch = domainRegex.Match(requestDomain);
比赛pathMatch = pathRegex.Match(requestPath); //路由数据
数据的RouteData = NULL;
如果(domainMatch.Success&放大器;&放大器; pathMatch.Success&放大器;&放大器;!requestDomain.ToLower()=tg.local与&&放大器;
requestDomain.ToLower()=tg.terrasynq.net&放大器;!&安培; requestDomain.ToLower()=www.townsgossip.com&放大器;!&安培;
requestDomain.ToLower()!=townsgossip.com)
{
数据=新的RouteData(这一点,RouteHandler); //首先添加默认值
如果(默认值!= NULL)
{
的foreach(KeyValuePair<字符串对象>在默认项)
{
data.Values [item.Key] = item.Value;
}
} //迭代匹配域组
的for(int i = 1; I< domainMatch.Groups.Count;我++)
{
群组= domainMatch.Groups [I]
如果(group.Success)
{
字符串键= domainRegex.GroupNameFromNumber(I) 如果(string.IsNullOrEmpty(键)及!&安培;!char.IsNumber(键,0))
{
如果(!string.IsNullOrEmpty(group.Value))
{
data.Values [关键] = group.Value;
}
}
}
} //迭代匹配路径组
的for(int i = 1; I< pathMatch.Groups.Count;我++)
{
群组= pathMatch.Groups [I]
如果(group.Success)
{
字符串键= pathRegex.GroupNameFromNumber(I) 如果(string.IsNullOrEmpty(键)及!&安培;!char.IsNumber(键,0))
{
如果(!string.IsNullOrEmpty(group.Value))
{
data.Values [关键] = group.Value;
}
}
}
}
} 返回的数据;
} 公众覆盖VirtualPathData GetVirtualPath(RequestContext的的RequestContext,RouteValueDictionary值)
{
返回base.GetVirtualPath(RequestContext的,RemoveDomainTokens(值));
} 公共DomainData GetDomainData(RequestContext的的RequestContext,RouteValueDictionary值)
{
//主机构建
字符串主机名=域名;
的foreach(KeyValuePair<字符串对象>对价值观)
{
主机名= hostname.Replace({+ pair.Key +},pair.Value.ToString());
} //返回域数据
返回新DomainData
{
协议=HTTP,
HOSTNAME =主机名,
片段=
};
} 私人正则表达式CreateRegex(字符串源)
{
//执行替换
来源= source.Replace(/,@\\ /?);
来源= source.Replace(@\\?,);
来源= source.Replace( - ,@\\ - ?);
来源= source.Replace({,@(小于?);
来源= source.Replace(},@>([A-ZA-Z0-9 _ \\ - ] *))); 返回新正则表达式(^+源+$);
} 私人RouteValueDictionary RemoveDomainTokens(RouteValueDictionary值)
{
VAR tokenRegex =
新正则表达式(
@\"({[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_\\-]*})*\\.?\\/?\");
比赛tokenMatch = tokenRegex.Match(域);
的for(int i = 0; I< tokenMatch.Groups.Count;我++)
{
群组= tokenMatch.Groups [I]
如果(group.Success)
{
字符串键= group.Value.Replace({,).Replace(},);
如果(values.ContainsKey(键))
values.Remove(键);
}
} 返回值;
}
}
I realize there are a few articles on similar things but none of which has helped me.
I have a single web app with multiple domains pointing to the same app. I would like to know how I can map a route to a specific controller based on the domain that is trying to access the web app.
What I currently tried is the following with no success.
routes.MapRoute(
name: "WowPoetry",
url: "wowpoetry.org/{action}/{id}",
defaults: new { controller = "Wow", action = "Index", id = UrlParameter.Optional }
);
I ended up following this tutorial to achieve what I wanted to with the exception of I used to to do domain routing and not subdomain routing.
Domain Routing Tutorial ASP.Net MVC
Implementation:
routes.Add(new DomainRoute("wowpoetry.org", "", new { controller = "Wow", action = "Index" }));
DomainData.cs
public class DomainData
{
public string Protocol { get; set; }
public string HostName { get; set; }
public string Fragment { get; set; }
}
DomainRoute.cs
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;
}
}
这篇关于域间路由的MVC5的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!