ASP.NET MVC 实现二级域名
自從微軟發(fā)布 ASP.NET MVC 和routing engine (System.Web.Routing)以來,就設(shè)法讓我們明白你完全能控制URL和routing,只要與你的application path相結(jié)合進(jìn)行擴(kuò)展,任何問題都迎刃而解。如果你需要在所處的域或者子域處理數(shù)據(jù)標(biāo)記的話,強(qiáng)制使用Default。
遺憾的是,ASP.NET MVC是基于虛擬目錄的,在實(shí)際項(xiàng)目卻有各種各樣的需求方案。
例如:
1:應(yīng)用程序是多語言的,像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}....” 。
坐下來,深呼吸,開始我們ASP.NET MVC的神奇之旅吧。
定義routes
?
下面是我們定義簡(jiǎn)單的route,不帶任何controller控制的route:
?
Code routes.Add("DomainRoute", new DomainRoute( "home.example.com", // Domain with parameters"{action}/{id}",??? // URL with parametersnew { controller ="Home", action ="Index", id ="" }? // Parameter defaults));另一個(gè)例子是用我們的controller控制域名:
?
Code routes.Add("DomainRoute", new DomainRoute( "{controller}.example.com",???? // Domain with parameters< br />??? "{action}/{id}",??? // URL with parametersnew { controller ="Home", action ="Index", id ="" }? // Parameter defaults));打算用controller 和action完全控制域名?
?
Code routes.Add("DomainRoute", new DomainRoute( "{controller}-{action}.example.com",???? // Domain with parameters"{id}",??? // URL with parametersnew { controller ="Home", action ="Index", id ="" }? // Parameter defaults));接下來是多語言route:
Code routes.Add("DomainRoute", new DomainRoute( "{language}.example.com",???? // Domain with parameters"{controller}/{action}/{id}",??? // URL with parametersnew { 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或沒有。利用這些,現(xiàn)在您可以添加一個(gè)鏈接到一個(gè)Action如下:
?
<%= Html.ActionLink("About", "About", "Home", true)%>跟你以往的習(xí)慣沒有什么不同,不是嗎? 以下是一小段代碼:
?
Code publicstaticclass LinkExtensions { publicstaticstring 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 thesepublicstaticstring 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); ??? } }
在這沒什么特別的:有許多的擴(kuò)展方法,把擴(kuò)展的URL加到域名上。這是一個(gè)預(yù)設(shè)ActionLink helpers,我的精神食糧來了DomainRoute class(詳見:Dark Magic)
Dark magic
瞥眼之間,您可能已經(jīng)看到了我的DomainRoute類代碼段。這個(gè)類實(shí)際上是提取子域,并增加了象征性支持域部分的傳入的URL,
我們將擴(kuò)展基類,它已經(jīng)給了我們一些屬性和方法,但是我們得重寫他們!
?
Code publicclass DomainRoute : Route {? // publicstring Domain { get; set; }// publicoverride 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; ??? }
publicoverride VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) ??? { returnbase.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ù)returnnew 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開發(fā)Web服務(wù)器,務(wù)必添加把二級(jí)域名添加到hosts文件)(貌似本地測(cè)試不用) 原文地址:http://blog.maartenballiauw.be/post/2009/05/20/ASPNET-MVC-Domain-Routing.aspx 其實(shí)有的人為什么要這么麻煩用這種方式,URL重寫或者二級(jí)域名直接綁定都可以。但是既然微軟給url rouring,就應(yīng)該能做到。
轉(zhuǎn)自:http://www.cnblogs.com/luanwey/archive/2009/08/12/1544444.html
轉(zhuǎn)載于:https://www.cnblogs.com/cuihongyu3503319/p/3408400.html
總結(jié)
以上是生活随笔為你收集整理的ASP.NET MVC 实现二级域名的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2013-10-31 《三天里什么都没干
- 下一篇: dos下的edit命令使用详解