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

自从微软发布 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 = ""
        }; 
    }

// 
}

 

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

附代码:附件
(如果要在使用Visual Studio开发Web服务器,务必添加把二级域名添加到hosts文件)(貌似本地测试不用)
原文地址:http://blog.maartenballiauw.be/post/2009/05/20/ASPNET-MVC-Domain-Routing.aspx
其实有的人为什么要这么麻烦用这种方式,URL重写或者二级域名直接绑定都可以。但是既然微软给url rouring,就应该能做到。

转载于:https://www.cnblogs.com/haiyabtx/archive/2013/04/02/2996097.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/261850.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

list和tuple

2019独角兽企业重金招聘Python工程师标准>>> list Python内置的一种数据类型是列表&#xff1a;list。list是一种有序的集合&#xff0c;可以随时添加和删除其中的元素。 比如&#xff0c;列出班里所有同学的名字&#xff0c;就可以用一个list表示&#xff1a; >…

springboot数据源不正确_Spring MVC 到 Spring Boot 的简化之路

Spring全家桶笔记&#xff1a;SpringSpring BootSpring CloudSpring MVC​shimo.im01 背景从Servlet技术到Spring和Spring MVC&#xff0c;开发Web应用变得越来越简捷。但是Spring和Spring MVC的众多配置有时却让人望而却步&#xff0c;相信有过Spring MVC开发经验的朋友能深刻…

KDT#94 为DW/BI系统建立定制工具

Building Custom Tools for the DW/BI System 市场上有大量的工具帮我们来建立DW/BI系统、把信息交付给业务用户。这些工具的种类也很多&#xff0c;它们包括关系型数据库管理系统、OLAP数据库管理系统、ETL工具、数据挖掘工具、查询工具、报表工具&#xff0c;以及BI门户工具等…

c盘所有的html文件全删,我将C盘文件夹全删了

如果删除了系统文件系统运行就会出现错误&#xff0c;如果系统运行稳定就说明没有删除系统重要文件&#xff0c;建议今后删除文件时尽量弄清楚后在删除&#xff0c;如果系统出现问题&#xff0c;可以按照下面方法修复。1、请你用系统自带的系统还原&#xff0c;还原到你没有出现…

OSSIM主要数据库表结构

OSSIM主要数据库表结构对于从事OSSIM开发的技术人员&#xff0c;最主要的需要知道OSSIM库里的多种表结构&#xff0c;下面举几个典型事例&#xff1a;/* config表 */DROP TABLE IF EXISTS conf;CREATE TABLE conf (recovery int NOT NULL,threshold int NOT NUL…

C#线程同步(1)- 临界区&Lock .

预备知识&#xff1a;线程的相关概念和知识&#xff0c;有多线程编码的初步经验。 一个机会&#xff0c;索性把线程同步的问题在C#里面的东西都粗略看了下。 第一印象&#xff0c;C#关于线程同步的东西好多&#xff0c;保持了C#一贯的大杂烩和四不象风格(Java/Delphi)。临界区跟…

python atm银行取款系统_Python实现ATM系统

今天偶尔在知乎上看到某大佬用Python写的ATM系统案例&#xff0c;然后观摩了下他的实现思路和源码&#xff0c;感觉受益颇多&#xff0c;于是就根据自己的思路和目前掌握的Python编程基础将ATM实现了一下&#xff0c;以下是案例解析的过程&#xff1a;案例剖析&#xff1a;1.at…

【摘录】BREW应用的c++实现注意点

BREW应用的c实现注意点 从VC6.0的调试器来说吧&#xff0c;肯定支持C语言了&#xff0c;对于ARM或者GCC来说&#xff0c;也是有可用的C编译器&#xff0c;而且任何支持BREW的手机都可以运行通过ARM或者GCC编译连接出来的目标代码&#xff0c;所以从环境来说&#xff0c;BREW开发…

MapXtreme 包含所有自带坐标系一览

CoordSys 对象包含关于 X 和 Y 坐标如何与其在 Earth 上的位置相关联的基本信息。 每个 Geometry 或 Map 对象都有一个关联的坐标系。 CoordSys 对象包含对坐标系的详细说明。 CoordSysFactory 类提供了各种用于创建不同 CoordSys 对象的方法。 所有 CoordSys 对象都是只读的&a…

html4的语法,HTML——语法

文章目录页面结构一个标准的HTML页面如下&#xff1a;Document一、文档声明头标准的HTML页面&#xff0c;第一行是以开头的的语句&#xff0c;这就是文档声明头&#xff0c;即DocType Declaration&#xff0c;简称DTD。DTD可以告知浏览器使用哪种HTML或者XHTML规范。二、页面语…

如何学习streamdecoder类_2019年终巨献:一份拿下了阿里、网易、滴滴等大厂offer的学习笔记...

2019仅剩最后二十天&#xff0c;回顾今年初遇“寒冬”时&#xff0c;自己也挺慌的&#xff0c;但是经历过这么多次面试后&#xff0c;我才“醒悟”&#xff0c;所谓的“寒冬”&#xff0c;“冻死”的都是“衣服穿的少的”。年末了在这里做一个年度总结&#xff0c;今年面试了不…

自定义控件的构建(12)

Share 前面讲了模板的构建&#xff0c;我们忽略了一个细节&#xff0c;如果接触ASP.NET时间不长的话&#xff0c;一般都会看到数据表达式是<%#Eval(‘Name’)%>这种形式的&#xff0c; 那么我们为什么用<%#Container.Name%>这种形式呢&#xff0c;其实前者是ASP.NE…

矩阵快速幂 zoj-3690 Choosing number

题目链接&#xff1a; http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId4973 题目意思&#xff1a; 有n个人&#xff0c;有1——m个数&#xff0c;每个人可以选择1个数&#xff0c;要求相邻的两个人如果选的数相同则必须大于k,求选数的种数。 解题思路&#xff1a…

insertAfter()

<div id"b">bbbbbbbbb</div> <div>dddddd</div> JavaScript window.οnlοadfunction(){var a document.createElement("span");var b document.createTextNode("cssrain");a.appendChild(b);var mubiao document.getE…

python def 参数一直为false_在Python 3中,如果参数为False,则查找惯用的方法来评估为False...

我有一连串的功能,全部定义在课程其他地方&#xff1a;fus(roh(dah(inp)))其中inp是字典或bool(False).期望的结果是,如果inp或任何函数评估为False,则False由函数堆返回.我试图使用三元运算符,但是它们不能正确评估.def func(inp):return int(inp[value]) 1 if inp else Fals…

复试计算机网络与软件工程,2018华南理工大学软件工程复试经验贴

尘埃落定&#xff0c;昨天结束了复试&#xff0c;终于被拟录取了&#xff0c;只有真正经历过才知道不容易&#xff0c;一年来受到王道的很多帮助&#xff0c;论坛上软件工程的信息相对来说还是比较少的&#xff0c;所以也想分享下自己的一些经验&#xff0c;帮助后来人。本人普…

学计算机等级考试电脑版软件,计算机二级考试宝典电脑版

计算机二级考试宝典电脑版是一款专业的二级计算机内容学习软件。该软件由武汉大学团队真情研发&#xff0c;软件包含选择题1600道&#xff0c;非选择题109套&#xff0c;成功实现了考点和重点的全面覆盖式学习目的&#xff0c;对学生们学习起到了巨大的帮助。该版本是通过安卓模…

mysq进阶

学习资料&#xff1a; 官方文档&#xff1a;http://dev.mysql.com/doc/refman/5.0/en/tutorial.html 1.存储过程&#xff1a; 优点&#xff1a;业务逻辑封装在存储过程中&#xff0c;容易维护&#xff0c;执行效率也高。 缺点&#xff1a;不同的数据库功能函数等不一样&#xf…

归纳整理--第4篇--常用软件

CSDN博客不再经常更新&#xff0c;更多优质文章请来 粉丝联盟网 FansUnion.cn! (FansUnion) 随着软硬件设施的提高和网民网络生活的丰富&#xff0c;电脑上的软件越来越多。对于一个专业开发者来说&#xff0c;尤其如此。常用软件主要分2类。1.娱乐休闲类。普通网民使用的一些软…

获取主机的信息

BOOL GetLocalHostInfo(){   //得到主机名称   int nComputerNameLen;   nComputerNameLen MAX_COMPUTERNAME_LENGTH 1;   if(SOCKET_ERROR gethostname(m_chLocalHostName,nComputerNameLen))     return FALSE;   ///end//   ///得到主机IP地址   HOST…