欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-07-02 14:22:17
先分析需求 在MVC项目中,我们如果有两个Areas。比如Test和DEMO。我们的访问地址应该是 http://localhost:8098/test http://localhost:8098/demo 如果我们绑定域名后想实现这样访问 http://test.abc.com:8098/ htt ......

先分析需求

在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类。

asp.net  MVC把Areas区域绑定成二级域名
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。主要存储域名和路由之间的存储关联。

asp.net  MVC把Areas区域绑定成二级域名
 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的类了

asp.net  MVC把Areas区域绑定成二级域名
 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查找到域名。

asp.net  MVC把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区域里面绑定路由的地方加入一下代码

asp.net  MVC把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的方式访问的

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

同理demo区域也添加代码。

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

访问后的效果

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

本文参考文章地址

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