当前位置: 移动技术网 > IT编程>开发语言>.net > asp.net MVC把Areas区域绑定成二级域名

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

2018年10月31日  | 移动技术网IT编程  | 我要评论

2017世乒赛赛程,淘宝网9.9元包邮,吉安二手房网

先分析需求

在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.html。可惜都是破坏了原来项目的结构,对于已经上线的项目不太适用。

本文的解决办法实在不破坏原来的结构之上,在原来的areas里面重新绑定新的路由规则,重写基类路由 routebase的getroutedata方法达到绑定二级域名,访问areas的方法。

前期准备工作你需要先修改本地host文件,绑定一些二级域名。比如 

127.0.0.1 demo.abc.com

127.0.0.1 test.abc.com

首先新建 areadomainregistrationcontext类。

public class areadomainregistrationcontext
    {
        /// <summary>
        ///
        /// </summary>
        /// <param name="_domainname">子域名 如:www.xxx.com 可以传 abc</param>
        public areadomainregistrationcontext(arearegistrationcontext _context, string _domainname)
        {
            domainname = _domainname; context = _context;
        }
        private string domainname; private arearegistrationcontext context;
        private routecollection routes
        {
            get
            {
                if (!domainroutetable.domainroutes.containskey(domainname))
                {
                    domainroutetable.domainroutes[domainname] = new routecollection();
                }
                return domainroutetable.domainroutes[domainname];
            }
        }


        public route maproute(string name, string url, object defaults, object constraints = null, string[] namespaces = null)
        {
            if (namespaces == null && context.namespaces != null)
            {
                namespaces = context.namespaces.toarray();
            }

            route route = routes.maproute(name, url, defaults, constraints, namespaces);
            route.datatokens["area"] = context.areaname;
            route.datatokens["usenamespacefallback"] = false;
            route.datatokens["subdomain"] = domainname;
            return route;
        }
    }
view code

 domainroutetable类里面有一个静态属性domainroutes。主要存储域名和路由之间的存储关联。

 public class domainroutetable
    {
        private static dictionary<string, routecollection> _instance = new dictionary<string, routecollection>();

        public static dictionary<string, routecollection> domainroutes
        {
            get
            {
                return _instance;
            }
        }
    }
view code

下面就是重写routebase的类了

 public class domainroute : routebase
    {
        public resolvedomainname resolvedomainname = dependencyresolver.current.getservice<resolvedomainname>();
        public routedata d = new routedata(null, new stoproutinghandler());

        public override routedata getroutedata(httpcontextbase httpcontext)
        {
            string domainname = resolvedomainname.resolve(httpcontext);
            //该主机头没有配置,返回 null 继续查找路由
            if (domainname == null) return null;

            if (!domainroutetable.domainroutes.containskey(domainname)) return d;

            var rs = domainroutetable.domainroutes[domainname];
            routedata routedata = rs.getroutedata(httpcontext);
            if (routedata == null) return d;
            return routedata;
        }

        public override virtualpathdata getvirtualpath(requestcontext requestcontext, routevaluedictionary values)
        {
            string domainname = resolvedomainname.resolve(requestcontext.httpcontext);

            if (domainname == null) return null;
            if (!domainroutetable.domainroutes.containskey(domainname)) return null;

            var rs = domainroutetable.domainroutes[domainname];
            virtualpathdata vpd = rs.getvirtualpathforarea(requestcontext, values);
            return vpd;
        }
    }
view code

resolvedomainname主要映射areas和域名之间的关系,可以根据areas查找到域名。

 public class resolvedomainname
    {
        public static dictionary<string, string> domainmap = new dictionary<string, string>(stringcomparer.ordinalignorecase);
        public string resolve(httpcontextbase httpcontext)
        {
            string key = httpcontext.request.headers["host"];
            string value;
            if (domainmap.trygetvalue(key, out value)) { return value; }
            else return null;
        }
    }
view code

 

接下来在global文件的里面的application_start方法里面的第一行加入一下代码

routetable.routes.add(new domainroute());
resolvedomainname.domainmap.add("demo.abc.com:8098", "demo1");

resolvedomainname.domainmap.add("test.abc.com:8098", "test");

这样就可以绑定多个域名,后面的demo1和test可以不和areas的名称相等,这里这是一个key而已。

接着在areas区域里面绑定路由的地方加入一下代码

 var context2 = new areadomainregistrationcontext(context, "test");

            context2.maproute(
                name: "test_default",
                url: "{controller}/{action}",
                defaults: new { controller = "home", action = "index" },
               namespaces: new string[] { "webapplication1.areas.test.controllers" });
view code

代码看起来是这样的,这样并不影响之前的访问,还是可以通过areas的方式访问的

同理demo区域也添加代码。

接着编译我们的项目,就可以用demo.abc.com:8098来访问了,是不是很简单。

访问后的效果

本文参考文章地址

https://www.cnblogs.com/hitearth/p/6848788.html

 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网