zoukankan      html  css  js  c++  java
  • 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.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

  • 相关阅读:
    将new Date()的时间转换为常用时间格式
    封装通用的jsonp方式
    javascript实现手机震动API代码
    webstorm 2016.3.2 破解代码(免费)
    淘宝镜像在npm中执行的代码
    jQuery lazyload 懒加载
    uniapp小程序获取时间戳转换时间例子
    微信小程序解析HTML标签
    微信小程序之tab切换效果
    巧用weui.gallery(),点击图片后预览图片
  • 原文地址:https://www.cnblogs.com/Playfunny/p/9875342.html
Copyright © 2011-2022 走看看