之前我就想做二级域名指向同一个IP同一个程序无非是在路由匹配规则上做文章也就是对Url的重写的一种思路。我用了半天时间上网查阅了相关资料并做了Demo测试是完全

以的,在这分享给大家...

假如网站主域名是:www.abc.com

实现二级域名是:     tianjin.abc.com , shanxi.abc.com 这个样子。

首先定义DomainData、DomainRoute类

public class DomainRoute : Route
{
private Regex domainRegex;
private Regex pathRegex; public string Domain { get; set; } public DomainRoute(string domain, string url, RouteValueDictionary defaults)
: base(url, defaults, new MvcRouteHandler())
{
Domain = domain;
} public DomainRoute(string domain, string url, RouteValueDictionary defaults, IRouteHandler routeHandler)
: base(url, defaults, routeHandler)
{
Domain = domain;
} public DomainRoute(string domain, string url, object defaults)
: base(url, new RouteValueDictionary(defaults), new MvcRouteHandler())
{
Domain = domain;
} public DomainRoute(string domain, string url, object defaults, IRouteHandler routeHandler)
: base(url, new RouteValueDictionary(defaults), routeHandler)
{
Domain = domain;
} 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); // 路由数据
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 = ""
};
} private Regex CreateRegex(string source)
{
// 替换
source = source.Replace("/", @"\/?");
source = source.Replace(".", @"\.?");
source = source.Replace("-", @"\-?");
source = source.Replace("{", @"(?<");
source = source.Replace("}", @">([a-zA-Z0-9_]*))"); return new Regex("^" + source + "$");
} private RouteValueDictionary RemoveDomainTokens(RouteValueDictionary values)
{
Regex tokenRegex = new Regex(@"({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?({[a-zA-Z0-9_]*})*-?\.?\/?");
Match tokenMatch = tokenRegex.Match(Domain);
for (int i = 0; i < tokenMatch.Groups.Count; i++)
{
Group group = tokenMatch.Groups[i];
if (group.Success)
{
string key = group.Value.Replace("{", "").Replace("}", "");
if (values.ContainsKey(key))
values.Remove(key);
}
} return values;
}
}
    public class DomainData
    {
        public string Protocol { get; set; }
        public string HostName { get; set; }
        public string Fragment { get; set; }
    }

如果项目是MVC4.0那么就打开App_Start 文件夹下面的RouteConfig.cs路由配置文件,如果是MVC3.0项目则添加路由,Global.asax 文件默认的MVC 路由的代码

public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
); }

修改后的路由如下:

 public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.Add(
"@DomainRoute", new DomainRoute(
"abc.com",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
));
routes.Add(
"wwwDomainRoute", new DomainRoute(
"www.abc.com",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
));
routes.Add(
"DomainRoute", new DomainRoute(
"{CityNameUrl}.abc.com",
"{controller}/{action}/{id}",
new { CityNameUrl = "", controller = "Home", action = "City", id = "" }
));
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
); }

当然这个路由解析匹配顺序是按照你们的需求去修改,但是路由匹配规则是从上到下的找符合的一条进行匹配,如果匹配到则不继续往下走,还需要说明一点, 我的域名是在万网注册的。所以还需要在域名解析那一块添加一条泛解析规则:

然后再程序中获取tianjin.abc.com 获取前缀名称tianjin这个动态参数的方法是:

var cityName = RouteData.Values["CityNameUrl"]; 就可以得到,

以上为个人学习总结,如有错误,欢迎指正!!共同学习研究!!!

参考地址:http://www.cnblogs.com/wenthink/archive/2013/04/10/MvcDynamicSecondaryDomain.html

http://blog.maartenballiauw.be/post/2009/05/20/ASPNET-MVC-Domain-Routing.aspx

转自:http://www.liguoqing.net/static/2014/12/15/50.html,感谢

ASP.NET MVC3.0或4.0设置二级域名的方法的更多相关文章

  1. 织梦dedecms移动版设置二级域名的方法 织梦如何设置m.开头的域名

    dedecms/' target='_blank'>织梦dedecms建站系统自从2015.06.18号升级后,系统增加了最强的手机站功能,模板与PC模板分开,标签90%类似,数据同步,很牛很强 ...

  2. 借助微软提供的url重写类库URLRewriter.dll(1.0)实现程序自动二级域名,域名需要泛解析

    二级域名和系统中会员帐号自动关联,也就是系统中注册一个会员,会员自动就可以通过二级域名来访问,比如我的帐号是zhangsan,我在morecoder.com注册后,访问zhangsan.morecod ...

  3. asp.net MVC把Areas区域绑定成二级域名

    先分析需求 在MVC项目中,我们如果有两个Areas.比如Test和DEMO.我们的访问地址应该是 http://localhost:8098/test http://localhost:8098/d ...

  4. 设置二级域名共享一级域名Cookie和删除共享Cookie

     设置共享Cookie: 二级域名要想共享一级域名的cookie,只需要设置cookie.Domain = ".一级域名.com";   删除共享Cookie:  HttpCook ...

  5. django 项目部署在 Apache 后, 设置二级域名(Apache虚拟主机 、 万网二级域名设置)

    上一篇文章简单说了怎么把django的项目部署到Apache上. 现在想弄个二级域名,也就是我原来有个域名 www.mysite.com,现在我想弄个 bbs.mysite.com ,该怎么做呢. 要 ...

  6. ASP.net获取当前页面的文件名,参数,域名等方法

    ASP.net后台获取当前页面的文件名 System.IO.Path.GetFileName(Request.Path).ToString(); 获取当前页面文件名,参数,域名等方法 假设当前页完整地 ...

  7. Apache设置二级域名和虚拟主机

    apache  httpd.conf 最后: ------------------------------NameVirtualHost *:80<VirtualHost *:80>    ...

  8. 在ExpressJS中设置二级域名跨域共享Cookie

    问题:我使用expressjs和mongostore来管理session.下面是expressjs中的设置. app.configure(function(){ app.use(express.ses ...

  9. apache虚拟主机设置泛域名的方法

    在apache虚拟主机中设置泛域名解析,主要是用到ServerAlias 的配置. 1.支持多域名 例如,让mail.jbxue.org.smtp.jbxue.org.pop3.jbxue.org 都 ...

随机推荐

  1. wsdl和wadl区别

    [转]http://blog.csdn.net/liuxiao723846/article/details/51611183 1.Java开发WebService最重要的两个规范: JSR-224 ( ...

  2. JAVA-2-GetDay

    import java.util.*; public class Ch0310 { public static void main(String[] args) { // TODO 自动生成的方法存根 ...

  3. java数据流

    DataInputStream和DataOutputStream提供了可以直接存取java基本类型(int,double等)的方法.对于存取基本类型,在效率上比普通字节流要快很多.它们分别继承inpu ...

  4. 异步socket大并发实现

    using System;using System.Collections.Generic;using System.Linq;using System.Net;using System.Net.So ...

  5. 在QT中使用Irrlicht引擎的方法与步骤

      Ø 相关库,插件安装部分 本篇文档介绍在Qt5.2.0下面使用lrrlicht引擎在Qt窗口中输出(开发环境:vs2012) 1. 首先安装好Qt5.2.0,下载地址: http://downlo ...

  6. Android Fragment用法之给Activity创建事件回调

    在某些案例中,可能需要Fragment与Activity共享事件.在Fragment内部定义一个回调接口是一个好方法,并且规定由持有它的Activity实现这个回调方法.当Activity通过接口接受 ...

  7. Postman 安装及使用入门教程(转)

    安装 本文只是基于 Chrome 浏览器的扩展插件来进行的安装,并非单独应用程序. 首先,你要台电脑,其次,安装有 Chrome 浏览器,那你接着往下看吧. 1. 官网安装(别看) 打开官网,http ...

  8. 学c语言做练习

    /*编写一个函数,其功能是使输入字符串反序.在一个使用循环语句为这个函数提供输入的完整 程序中进行测试.*/ #include<stdio.h> #include<string.h& ...

  9. ALTIUM 10 过孔设置开窗、不开窗

    大家或许会发现我们公司做的PCB板子,所有的过孔都开了窗,也就是说过孔没有绿油,这样会导致焊接中容易连焊.兴许大家为此吃进苦头,我是被整了好几次,查了好久却发现是个低级错误,一个过孔连焊到隔壁焊盘了. ...

  10. MFC动态创建按钮,并在按钮上实现位图的切换显示

    动态创建按钮,并在按钮中添加位图,通过单击按钮显示不同的位图,可设置为显示按钮按下和弹起两种状态.只要判断a值从而输入不同的响应代码. 1.在头文件中添加: CButton *pBtn; 2.在初始化 ...