ASP.NET MVC3.0或4.0设置二级域名的方法

之前我就想做二级域名指向同一个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,感谢

时间: 2024-11-10 04:27:32

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

解决tomcat中server.xml设置二级域名 [java.lang.OutOfMemoryError: PermGen space]

<Host name="XXX.XXX.XXX" debug="0" appBase="C:\\JavaWeb\\mytomcatServer\\XXX"  unpackWARs="true" autoDeploy="true"  xmlValidation="false" xmlNamespaceAware="false">  <Alias>

搭建二级网站遇到的问题:二.如何在阿里云主机中设置二级域名开通子网站

如何在阿里云主机中设置二级域名开通子网站,这个问题涉及到两步:一首先要做二级域名的A记录解析到服务器IP:二配置Apache的配置文件httpd.conf,让服务器识别该二级域名,然后重新加载httpd.conf文件即可: 二级域名的A记录解析到服务器IP 二级域名的A记录解析需要修改你域名DNS解析,比如我们要设置wordpress.webzhe.com到阿里云的主机IP,可以添加wordpress的二级域名(主机记录),选择A记录后,设置IP为阿里云的IP即可(主机记录值):通常这个解析是很

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

先分析需求 在MVC项目中,我们如果有两个Areas.比如Test和DEMO.我们的访问地址应该是 http://localhost:8098/test http://localhost:8098/demo 如果我们绑定域名后想实现这样访问 http://test.abc.com:8098/ http://demo.abc.com:8098/ 这个问题的相关解决办法倒是不少,比如http://www.cnblogs.com/jobily/archive/2011/10/09/2204800.ht

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

ASP.net后台获取当前页面的文件名 System.IO.Path.GetFileName(Request.Path).ToString(); 获取当前页面文件名,参数,域名等方法 假设当前页完整地址是:http://www.test.com/aaa/bbb.aspx?id=5&name=kelli "http://"是协议名 "www.test.com"是域名 "aaa"是虚拟目录名 "bbb.aspx"是页面名(

django 项目部署在 Apache 后, 设置二级域名

上一篇文章简单说了怎么把django的项目部署到Apache上. 现在想弄个二级域名,也就是我原来有个域名 www.mysite.com,现在我想弄个 bbs.mysite.com ,该怎么做呢. 要用到 Apache 的虚拟主机配置. 其实Apache的虚拟主机之前也配置过,有时有效,有时又不好用,也不知道个所以然.这次我详细的写一下每一步都要怎么做: 第一步:开启Apache虚拟主机功能: Apache的虚拟主机功能,默认是关闭的.如果要使用这个功能,就要开启虚拟主机功能. 如同上文提到的A

在wampserver3.0.6中配置虚拟主机(设置二级域名)

高版本(wampserver3.0.6中为apache2.4.23)apache的配置文件httpd.conf,关于虚拟主机的配置不同于低版本,遇到问题网上搜索到的解决方式大部分是低版本的.以下是通过调试的配置方式: 第一步:打开httpd.conf,去掉虚拟主机配置文件httpd-vhosts.conf注释 # Virtual hosts Include conf/extra/httpd-vhosts.conf 第二步:配置httpd-vhosts.conf文件 <VirtualHost *:

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

问题:我使用expressjs和mongostore来管理session.下面是expressjs中的设置. app.configure(function(){ app.use(express.session({ secret: conf.secret, maxAge: new Date(Date.now() + 3600000), cookie: { path: ‘/‘ }, store: new MongoStore(conf.db) })); }); 我已经在上面设置了cookie路径.但

linux下关于Apache设置二级域名绑定二级目录的方法

背景:对于一些论坛网站,某些目录需要制定二级域名去访问,这时候就要在apache中用二级域名绑定二级目录. 方法: 1.首先你要找到apache安装路径,在apahce安装路径下的conf文件夹中找到apache配置文件httpd.conf,打开配置文件,首先确定DocumentRoot路径注释掉(如果这个路径没有注释掉,那么不管用vhost还是用URL重写,都无法正常找到二级域名所绑定的二级目录) 2.开启mod_Rewrite这个模块,在httpd.conf配置文件中找到“#LoadModu

Apache 设置二级域名

开启重写模块 LoadModule rewrite_module modules/mod_rewrite.so 编辑配置 NameVirtualHost *:80 <VirtualHost *:80> DocumentRoot "/var/www/html" ServerName $DOMAIN_NAME ErrorLog "logs/error_log" CustomLog "logs/access_log" combined &l