asp.net 二级域名(路由方式实现)
自从微软发布 ASP.NET MVC 和routing engine (System.Web.Routing)以来,就设法让我们明白你完全能控制URL和routing,只要与你的application path相结合进行扩展,任何问题都迎刃而解。如果你需要在所处的域或者子域处理数据标记的话,强制使用Default。
遗憾的是,ASP.NET MVC是基于虚拟目录的,在实际项目却有各种各样的需求方案。
例如:
1:应用程序是多语言的,像cn.example.com应该被匹配到“www.{language}example.com”路由上。
2:应用程序是多用户的,像username.example.com应该被匹配到“www.{clientname}.example.com”路由上。
3:应用程序是多子域的,像mobile.example.com应该被匹配到"www.{controller}.example.com/{action}....” 。
坐下来,深呼吸,开始我们ASP.NET MVC的神奇之旅吧。
定义routes
下面是我们定义简单的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
));
另一个例子是用我们的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
));
接下来是多语言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 扩展方法
因为我们不希望所有的URL所产生HtmlHelper ActionLink要使用full URLs,第一件事我们会添加一些新的ActionLink,其中载有boolean flag是否要full URLs或没有。利用这些,现在您可以添加一个链接到一个Action如下:
<%= Html.ActionLink("About", "About", "Home", true)%>
跟你以往的习惯没有什么不同,不是吗?
以下是一小段代码:
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);
}
}
在这没什么特别的:有许多的扩展方法,把扩展的URL加到域名上。这是一个预设ActionLink helpers,我的精神食粮来了DomainRoute class(详见:Dark Magic)
Dark magic
瞥眼之间,您可能已经看到了我的DomainRoute类代码段。这个类实际上是提取子域,并增加了象征性支持域部分的传入的URL,
我们将扩展基类,它已经给了我们一些属性和方法,但是我们得重写他们!
public class DomainRoute : Route
{
// public string Domain { get; set; } // public override RouteData GetRouteData(HttpContextBase httpContext)
{
// 构造regex
domainRegex = CreateRegex(Domain);
pathRegex = CreateRegex(Url); // 请求信息
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 数据 RouteData data = null;
if (domainMatch.Success && pathMatch.Success)
{
data = new RouteData(this, RouteHandler); // 添加默认选项
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)
{
// 获得主机名 string hostname = Domain;
foreach (KeyValuePair<string, object> pair in values)
{
hostname = hostname.Replace("{" + pair.Key + "}", pair.Value.ToString());
} // Return 域名数据 return new DomainData
{
Protocol = "http",
HostName = hostname,
Fragment = ""
};
} //
}
asp.net 二级域名(路由方式实现)的更多相关文章
- ASP.NET二级域名站点共享Session状态
我的前面一篇文章提到了如何在使用了ASP.NET form authentication的二级站点之间共享登陆状态, http://www.cnblogs.com/jzywh/archive/2007 ...
- asp.net 二级域名表单认证情况下共享Cookie
二级域名之间共享Cookie,很重要的一点就是配置,如下: domain设置为.ahdqxx.com,如果你的域名是www.ahdqxx.com,mall.ahdqxx.com,那么请设置你的doma ...
- asp.net 二级域名session共享
1.自定义类 namespace SessionShare{ public class CrossDomainCookie : IHttpModule { private string m_RootD ...
- .NET MVC 二级域名路由的实现
.NET MVC 5以下版本: http://www.cnblogs.com/luanwey/archive/2009/08/12/1544444.html http://blog.maartenba ...
- 第二百六十八节,Tornado框架-路由映射之二级域名支持,html模板继承以及导入
Tornado框架-路由映射之二级域名支持,html模板继承以及导入 二级域名路由映射add_handlers()设置二级域名路由映射 注意:二级域名需要结合服务器ip绑定域名 框架引擎 #!/usr ...
- .net用url重写URLReWriter实现任意二级域名
.net用url重写URLReWriter实现任意二级域名 这两天需要用到URLReWriter来搞那个猪头的Blog,网上看到篇好文,收藏 摘要:解释了url重写的相关知识.用asp.net实现二级 ...
- [Linux.NET]Nginx 泛解析配置请求映射到多端口实现二级域名访问
由于想实现一个域名放置多个应用运行的目的,而不想通过域名后加端口号方式处理,这种方式处理记起来太麻烦,偷懒党简直不能忍,故而考虑了使用二级域名来处理多个应用同时运行.Google了一番资料并进行了尝试 ...
- .NET二级域名共享Session
ASP.NET二级域名站点共享Session状态 今天, 我要写的是如何在二级域名站点之间,主站点和二级域名站点之间共享Session. 首先, Session要共享,站点之间SessionID必须要 ...
- Nginx 泛解析配置请求映射到多端口实现二级域名访问
由于想实现一个域名放置多个应用运行的目的,而不想通过域名后加端口号方式处理,这种方式处理记起来太麻烦,偷懒党简直不能忍,故而考虑了使用二级域名来处理多个应用同时运行.Google了一番资料并进行了尝试 ...
随机推荐
- [POJ2068]Nim解题报告
Let's play a traditional game Nim. You and I are seated across a table and we have a hundred stones ...
- Git-cheatsheet
- Shell 脚本实现TCP/UDP协议通讯
Shell 脚本实现TCP/UDP协议通讯 http://www.cnblogs.com/occult/archive/2012/12/25/2832183.html
- JAVA 批量执行测试用例
如果多个测试用例在不同的类中,又需要一次性执行完所有的测试用例,则可以使用到Junit中的批量执行测试方法. 方法一 这种方式非常简单,不需要额外多写一行代码,Eclipse 本来就支持以项目或包为单 ...
- js的变量的有效域
function test(o) { var i=0; if(typeof o=="object") { var j=1; for(var k=0;k<10;k++) { c ...
- sublime text3插件TrailingSpaces无法使用的解决方法
TrailingSpaces是很好用的一款插件,可以清除代码结尾打多了几个空格或Tab,对于代码洁癖绝对是个福音,我的sublime text3本来安装了这款插件,也可以正常使用,今天突然不能用了,即 ...
- VisualStudio 2013开发Office插件
在VS中选择创建新项目,选择App for Office 选择mail出现的位置 Task pane The app appears in the task pane of a Microsift O ...
- scrapy snippet
1. spider文件 from scrapy.contrib.spiders import CrawlSpider, Rule from scrapy.contrib.linkextractors. ...
- CF 1003B Binary String Constructing 【构造/找规律/分类讨论】
You are given three integers a, b and x. Your task is to construct a binary string s of length n=a+b ...
- CF 917A The Monster 【括号匹配】
[链接]:CF Examples inputCopy ((?)) outputCopy 4 inputCopy ??()?? outputCopy 7 说明 For the first sample ...