自从微软发布 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 二级域名(路由方式实现)的更多相关文章

  1. ASP.NET二级域名站点共享Session状态

    我的前面一篇文章提到了如何在使用了ASP.NET form authentication的二级站点之间共享登陆状态, http://www.cnblogs.com/jzywh/archive/2007 ...

  2. asp.net 二级域名表单认证情况下共享Cookie

    二级域名之间共享Cookie,很重要的一点就是配置,如下: domain设置为.ahdqxx.com,如果你的域名是www.ahdqxx.com,mall.ahdqxx.com,那么请设置你的doma ...

  3. asp.net 二级域名session共享

    1.自定义类 namespace SessionShare{ public class CrossDomainCookie : IHttpModule { private string m_RootD ...

  4. .NET MVC 二级域名路由的实现

    .NET MVC 5以下版本: http://www.cnblogs.com/luanwey/archive/2009/08/12/1544444.html http://blog.maartenba ...

  5. 第二百六十八节,Tornado框架-路由映射之二级域名支持,html模板继承以及导入

    Tornado框架-路由映射之二级域名支持,html模板继承以及导入 二级域名路由映射add_handlers()设置二级域名路由映射 注意:二级域名需要结合服务器ip绑定域名 框架引擎 #!/usr ...

  6. .net用url重写URLReWriter实现任意二级域名

    .net用url重写URLReWriter实现任意二级域名 这两天需要用到URLReWriter来搞那个猪头的Blog,网上看到篇好文,收藏 摘要:解释了url重写的相关知识.用asp.net实现二级 ...

  7. [Linux.NET]Nginx 泛解析配置请求映射到多端口实现二级域名访问

    由于想实现一个域名放置多个应用运行的目的,而不想通过域名后加端口号方式处理,这种方式处理记起来太麻烦,偷懒党简直不能忍,故而考虑了使用二级域名来处理多个应用同时运行.Google了一番资料并进行了尝试 ...

  8. .NET二级域名共享Session

    ASP.NET二级域名站点共享Session状态 今天, 我要写的是如何在二级域名站点之间,主站点和二级域名站点之间共享Session. 首先, Session要共享,站点之间SessionID必须要 ...

  9. Nginx 泛解析配置请求映射到多端口实现二级域名访问

    由于想实现一个域名放置多个应用运行的目的,而不想通过域名后加端口号方式处理,这种方式处理记起来太麻烦,偷懒党简直不能忍,故而考虑了使用二级域名来处理多个应用同时运行.Google了一番资料并进行了尝试 ...

随机推荐

  1. 51nod加农炮

    这道题维护一下前缀最大值然后二分答案就好了哇 233 #include<cstdio> #include<cstring> #include<algorithm> ...

  2. [POJ2135]最小费用最大流

    一直由于某些原因耽搁着...最小费用最大流没有搞会. 今天趁着个人状态正佳,赶紧去看看,果然30min不到看会了算法+模板并且A掉了一道题. 感觉最小费用最大流在学过了最大流之后还是挺好理解的.找到从 ...

  3. TensorFlow_曲线拟合

    # coding:utf-8 import tensorflow as tf import numpy as np import matplotlib.pyplot as plt import os ...

  4. DWM.EXE进程(Desktop Window Manager)不能删除

    英文全拼:Desktop Window Manager(DWM) 进程描述:桌面窗口管理器文件位置:C:\Windows\System32进程简介:桌面窗口管理器是windows Vista及wind ...

  5. The Clean Architecture--一篇很不错的关于架构的文章

    翻译水平有限,见谅! Uncle Bob 13 Aug 2012 Architecture Craftsmanship Over the last several years we’ve seen a ...

  6. javascript 实现购物车页面

    跟商城有关系的网站,难免会有购物车的结账界面. 我用javascript实现了增加数量/减少数量,实时计算总金额,删除该商品,选中商品/反选商品/全选/全反选...的操作. 欢迎指点!~ 效果如图:( ...

  7. letsencrypt的证书转换上传到360网站防护方法

    命令:openssl 首先letsencrypt生成的证书在 letsencrypt/live/xxx.com/ 下,需要使用cert.pem和privkey.pem文件. 生成crt文件: open ...

  8. struts标签include传参的问题

    传一个常量过去居然为null, <s:include value="/biz/customer/corp/module/franchisemanageright/corpFranchi ...

  9. hammer.js触摸,手指缩放等许多手势操作

    使用方法: 插件描述:Hammer.js是一个开源的,轻量级的javascript库,它可以在不需要依赖其他东西的情况下识别触摸,鼠标事件. <script src="http://e ...

  10. 执行监听器( Execution listener)

    相关类: org.activiti.engine.delegate.ExecutionListener org.activiti.engine.delegate.TaskListener org.ac ...