2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > ASP.NET MVC 实现二级域名(泛域名)

ASP.NET MVC 实现二级域名(泛域名)

时间:2018-12-09 09:34:51

相关推荐

ASP.NET MVC 实现二级域名(泛域名)

自从微软发布 MVC 和routing engine (System.Web.Routing)以来,就设法让我们明白你完全能控制URL和routing,只要与你的application path相结合进行扩展,任何问题都迎刃而解。如果你需要在所处的域或者子域处理数据标记的话,强制使用Default。

遗憾的是, MVC是基于虚拟目录的,在实际项目却有各种各样的需求方案。

例如:

1:应用程序是多语言的,像应该被匹配到“www.{language}”路由上。

2:应用程序是多用户的,像应该被匹配到“www.{clientname}.”路由上。

3:应用程序是多子域的,像应该被匹配到"www.{controller}./{action}....” 。

坐下来,深呼吸,开始我们 MVC的神奇之旅吧。

定义routes

下面是我们定义简单的route,不带任何controller控制的route:

routes.Add("DomainRoute",newDomainRoute(

"",//Domainwithparameters

"{action}/{id}",//URLwithparameters

new{controller="Home",action="Index",id=""}//Parameterdefaults

));

另一个例子是用我们的controller控制域名:

routes.Add("DomainRoute",newDomainRoute(

"{controller}.",//Domainwithparameters<br/>"{action}/{id}",//URLwithparameters

new{controller="Home",action="Index",id=""}//Parameterdefaults

));

打算用controller 和action完全控制域名?

routes.Add("DomainRoute",newDomainRoute(

"{controller}-{action}.",//Domainwithparameters

"{id}",//URLwithparameters

new{controller="Home",action="Index",id=""}//Parameterdefaults

));

接下来是多语言route:

routes.Add("DomainRoute",newDomainRoute(

"{language}.",//Domainwithparameters

"{controller}/{action}/{id}",//URLwithparameters

new{language="en",controller="Home",action="Index",id=""}//Parameterdefaults

));

HtmlHelper 扩展方法

因为我们不希望所有的URL所产生HtmlHelper ActionLink要使用full URLs,第一件事我们会添加一些新的ActionLink,其中载有boolean flag是否要full URLs或没有。利用这些,现在您可以添加一个链接到一个Action如下:

<%=Html.ActionLink("About","About","Home",true)%>

跟你以往的习惯没有什么不同,不是吗?

以下是一小段代码:

publicstaticclassLinkExtensions

{

publicstaticstringActionLink(thisHtmlHelperhtmlHelper,stringlinkText,stringactionName,stringcontrollerName,boolrequireAbsoluteUrl)

{

returnhtmlHelper.ActionLink(linkText,actionName,controllerName,newRouteValueDictionary(),newRouteValueDictionary(),requireAbsoluteUrl);

}

//moreofthese

publicstaticstringActionLink(thisHtmlHelperhtmlHelper,stringlinkText,stringactionName,stringcontrollerName,RouteValueDictionaryrouteValues,IDictionary<string,object>htmlAttributes,boolrequireAbsoluteUrl)

{

if(requireAbsoluteUrl)

{

HttpContextBasecurrentContext=newHttpContextWrapper(HttpContext.Current);

RouteDatarouteData=RouteTable.Routes.GetRouteData(currentContext);

routeData.Values["controller"]=controllerName;

routeData.Values["action"]=actionName;

DomainRoutedomainRoute=routeData.RouteasDomainRoute;

if(domainRoute!=null)

{

DomainDatadomainData=domainRoute.GetDomainData(newRequestContext(currentContext,routeData),routeData.Values);

returnhtmlHelper.ActionLink(linkText,actionName,controllerName,domainData.Protocol,domainData.HostName,domainData.Fragment,routeData.Values,null);

}

}

returnhtmlHelper.ActionLink(linkText,actionName,controllerName,routeValues,htmlAttributes);

}

}

在这没什么特别的:有许多的扩展方法,把扩展的URL加到域名上。这是一个预设ActionLink helpers,我的精神食粮来了DomainRouteclass(详见:Dark Magic)

Dark magic

瞥眼之间,您可能已经看到了我的DomainRoute类代码段。这个类实际上是提取子域,并增加了象征性支持域部分的传入的URL,

我们将扩展基类,它已经给了我们一些属性和方法,但是我们得重写他们!

publicclassDomainRoute:Route

{

//

publicstringDomain{get;set;}

//

publicoverrideRouteDataGetRouteData(HttpContextBasehttpContext)

{

//构造regex

domainRegex=CreateRegex(Domain);

pathRegex=CreateRegex(Url);

//请求信息

stringrequestDomain=httpContext.Request.Headers["host"];

if(!string.IsNullOrEmpty(requestDomain))

{

if(requestDomain.IndexOf(":")>0)

{

requestDomain=requestDomain.Substring(0,requestDomain.IndexOf(":"));

}

}

else

{

requestDomain=httpContext.Request.Url.Host;

}

stringrequestPath=httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2)+httpContext.Request.PathInfo;

//匹配域名和路由

MatchdomainMatch=domainRegex.Match(requestDomain);

MatchpathMatch=pathRegex.Match(requestPath);

//Route数据

RouteDatadata=null;

if(domainMatch.Success&&pathMatch.Success)

{

data=newRouteData(this,RouteHandler);

//添加默认选项

if(Defaults!=null)

{

foreach(KeyValuePair<string,object>iteminDefaults)

{

data.Values[item.Key]=item.Value;

}

}

//匹配域名路由

for(inti=1;i<domainMatch.Groups.Count;i++)

{

Groupgroup=domainMatch.Groups[i];

if(group.Success)

{

stringkey=domainRegex.GroupNameFromNumber(i);

if(!string.IsNullOrEmpty(key)&&!char.IsNumber(key,0))

{

if(!string.IsNullOrEmpty(group.Value))

{

data.Values[key]=group.Value;

}

}

}

}

//匹配域名路径

for(inti=1;i<pathMatch.Groups.Count;i++)

{

Groupgroup=pathMatch.Groups[i];

if(group.Success)

{

stringkey=pathRegex.GroupNameFromNumber(i);

if(!string.IsNullOrEmpty(key)&&!char.IsNumber(key,0))

{

if(!string.IsNullOrEmpty(group.Value))

{

data.Values[key]=group.Value;

}

}

}

}

}

returndata;

}

publicoverrideVirtualPathDataGetVirtualPath(RequestContextrequestContext,RouteValueDictionaryvalues)

{

returnbase.GetVirtualPath(requestContext,RemoveDomainTokens(values));

}

publicDomainDataGetDomainData(RequestContextrequestContext,RouteValueDictionaryvalues)

{

//获得主机名

stringhostname=Domain;

foreach(KeyValuePair<string,object>pairinvalues)

{

hostname=hostname.Replace("{"+pair.Key+"}",pair.Value.ToString());

}

//Return域名数据

returnnewDomainData

{

Protocol="http",

HostName=hostname,

Fragment=""

};

}

//

}

哇,这是一串按照我们定义的route转换传入请求的URL到tokens的代码,我们这样做是转换{controller}和按照regex然后再尝试匹配route规则,在我们的DomainRouteclass里还有其他的helper方法,需要更多的功能可以自己研究扩展。

附代码:附件

(如果要在使用Visual Studio开发Web服务器,务必添加把二级域名添加到hosts文件)(貌似本地测试不用)

原文地址:http://blog.maartenballiauw.be/post//05/20/ASPNET-MVC-Domain-Routing.aspx

其实有的人为什么要这么麻烦用这种方式,URL重写或者二级域名直接绑定都可以。但是既然微软给url rouring,就应该能做到。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。