ASP.NET MVC 实现二级域名(泛域名)
自從微軟發(fā)布 ASP.NET MVC 和routing engine (System.Web.Routing)以來(lái),就設(shè)法讓我們明白你完全能控制URL和routing,只要與你的application path相結(jié)合進(jìn)行擴(kuò)展,任何問(wèn)題都迎刃而解。如果你需要在所處的域或者子域處理數(shù)據(jù)標(biāo)記的話,強(qiáng)制使用Default。
遺憾的是,ASP.NET MVC是基于虛擬目錄的,在實(shí)際項(xiàng)目卻有各種各樣的需求方案。
例如:
1:應(yīng)用程序是多語(yǔ)言的,像cn.example.com應(yīng)該被匹配到“www.{language}example.com”路由上。
2:應(yīng)用程序是多用戶的,像username.example.com應(yīng)該被匹配到“www.{clientname}.example.com”路由上。
3:應(yīng)用程序是多子域的,像mobile.example.com應(yīng)該被匹配到"www.{controller}.example.com/{action}....” 。
坐下來(lái),深呼吸,開(kāi)始我們ASP.NET MVC的神奇之旅吧。
定義routes
?
下面是我們定義簡(jiǎn)單的route,不帶任何controller控制的route:
?
routes.Add("DomainRoute",?new?DomainRoute(?
"home.example.com",?//?Domain?with?parameters
"{action}/{id}",????//?URL?with?parameters
new?{?controller?=?"Home",?action?=?"Index",?id?=?""?}??//?Parameter?defaults
));
另一個(gè)例子是用我們的controller控制域名:
?
routes.Add("DomainRoute",?new?DomainRoute(?
"{controller}.example.com",?????//?Domain?with?parameters<?br?/>????"{action}/{id}",????//?URL?with?parameters
new?{?controller?=?"Home",?action?=?"Index",?id?=?""?}??//?Parameter?defaults
));
打算用controller 和action完全控制域名?
?
routes.Add("DomainRoute",?new?DomainRoute(?
"{controller}-{action}.example.com",?????//?Domain?with?parameters
"{id}",????//?URL?with?parameters
new?{?controller?=?"Home",?action?=?"Index",?id?=?""?}??//?Parameter?defaults
));
接下來(lái)是多語(yǔ)言route:
routes.Add("DomainRoute",?new?DomainRoute(?
"{language}.example.com",?????//?Domain?with?parameters
"{controller}/{action}/{id}",????//?URL?with?parameters
new?{?language?=?"en",?controller?=?"Home",?action?=?"Index",?id?=?""?}??//?Parameter?defaults
));
HtmlHelper 擴(kuò)展方法
因?yàn)槲覀儾幌M械腢RL所產(chǎn)生HtmlHelper ActionLink要使用full URLs,第一件事我們會(huì)添加一些新的ActionLink,其中載有boolean flag是否要full URLs或沒(méi)有。利用這些,現(xiàn)在您可以添加一個(gè)鏈接到一個(gè)Action如下:
?
<%=Html.ActionLink("About",?"About",?"Home",?true)%>跟你以往的習(xí)慣沒(méi)有什么不同,不是嗎?
以下是一小段代碼:
?
public?static?class?LinkExtensions?
{?
public?static?string?ActionLink(this?HtmlHelper?htmlHelper,?string?linkText,?string?actionName,?string?controllerName,?bool?requireAbsoluteUrl)?
????{?
return?htmlHelper.ActionLink(linkText,?actionName,?controllerName,?new?RouteValueDictionary(),?new?RouteValueDictionary(),?requireAbsoluteUrl);?
????}?
//?more?of?these?
public?static?string?ActionLink(this?HtmlHelper?htmlHelper,?string?linkText,?string?actionName,?string?controllerName,?RouteValueDictionary?routeValues,?IDictionary<string,?object>?htmlAttributes,?bool?requireAbsoluteUrl)?
????{?
if?(requireAbsoluteUrl)?
????????{?
????????????HttpContextBase?currentContext?=?new?HttpContextWrapper(HttpContext.Current);?
????????????RouteData?routeData?=?RouteTable.Routes.GetRouteData(currentContext);?
????????????routeData.Values["controller"]?=?controllerName;?
????????????routeData.Values["action"]?=?actionName;?
????????????DomainRoute?domainRoute?=?routeData.Route?as?DomainRoute;?
if?(domainRoute?!=?null)?
????????????{?
????????????????DomainData?domainData?=?domainRoute.GetDomainData(new?RequestContext(currentContext,?routeData),?routeData.Values);?
return?htmlHelper.ActionLink(linkText,?actionName,?controllerName,?domainData.Protocol,?domainData.HostName,?domainData.Fragment,?routeData.Values,?null);?
????????????}?
????????}?
return?htmlHelper.ActionLink(linkText,?actionName,?controllerName,?routeValues,?htmlAttributes);?
????}?
}
在這沒(méi)什么特別的:有許多的擴(kuò)展方法,把擴(kuò)展的URL加到域名上。這是一個(gè)預(yù)設(shè)ActionLink helpers,我的精神食糧來(lái)了DomainRoute?class(詳見(jiàn):Dark Magic)
Dark magic
瞥眼之間,您可能已經(jīng)看到了我的DomainRoute類代碼段。這個(gè)類實(shí)際上是提取子域,并增加了象征性支持域部分的傳入的URL,
我們將擴(kuò)展基類,它已經(jīng)給了我們一些屬性和方法,但是我們得重寫(xiě)他們!
?
public?class?DomainRoute?:?Route?
{??
//??
public?string?Domain?{?get;?set;?}?
//??
public?override?RouteData?GetRouteData(HttpContextBase?httpContext)?
????{?
//?構(gòu)造regex
????????domainRegex?=?CreateRegex(Domain);?
????????pathRegex?=?CreateRegex(Url);?
//?請(qǐng)求信息
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?domainMatch?=?domainRegex.Match(requestDomain);?
????????Match?pathMatch?=?pathRegex.Match(requestPath);
//?Route?數(shù)據(jù)
????????RouteData?data?=?null;?
if?(domainMatch.Success?&&?pathMatch.Success)?
????????{?
????????????data?=?new?RouteData(this,?RouteHandler);
//?添加默認(rèn)選項(xiàng)
if?(Defaults?!=?null)?
????????????{?
foreach?(KeyValuePair<string,?object>?item?in?Defaults)?
????????????????{?
????????????????????data.Values[item.Key]?=?item.Value;?
????????????????}?
????????????}?
//?匹配域名路由
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;?
????????????????????????}?
????????????????????}?
????????????????}?
????????????}?
//?匹配域名路徑
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)?
????{?
//?獲得主機(jī)名
string?hostname?=?Domain;?
foreach?(KeyValuePair<string,?object>?pair?in?values)?
????????{?
????????????hostname?=?hostname.Replace("{"?+?pair.Key?+?"}",?pair.Value.ToString());?
????????}
//?Return?域名數(shù)據(jù)
return?new?DomainData?
????????{?
????????????Protocol?=?"http",?
????????????HostName?=?hostname,?
????????????Fragment?=?""
????????};?
????}
//?
}
?
哇,這是一串按照我們定義的route轉(zhuǎn)換傳入請(qǐng)求的URL到tokens的代碼,我們這樣做是轉(zhuǎn)換{controller}和按照regex然后再嘗試匹配route規(guī)則,在我們的DomainRoute?class里還有其他的helper方法,需要更多的功能可以自己研究擴(kuò)展。
附代碼:附件
(如果要在使用Visual Studio開(kāi)發(fā)Web服務(wù)器,務(wù)必添加把二級(jí)域名添加到hosts文件)(貌似本地測(cè)試不用)
原文地址:http://blog.maartenballiauw.be/post/2009/05/20/ASPNET-MVC-Domain-Routing.aspx
其實(shí)有的人為什么要這么麻煩用這種方式,URL重寫(xiě)或者二級(jí)域名直接綁定都可以。但是既然微軟給url rouring,就應(yīng)該能做到。
轉(zhuǎn)載于:https://www.cnblogs.com/haiyabtx/archive/2013/04/02/2996097.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的ASP.NET MVC 实现二级域名(泛域名)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: VISA信用卡怎么样?国内哪家银行的VI
- 下一篇: ASP.NET MVC 5 学习教程:控