zoukankan      html  css  js  c++  java
  • MVC动态二级域名解析

    动态二级域名的实现:

    应用场景:目前产品要实现block功能,因为工作需要实现二级域名:www.{CompanyUrl}.xxx.com

    假设产品主域名入口为:www.xxx.com

    公司员工管理:www.a.xxx.com

    公司产品管理: www.b.xxx.com

    Route简介:ASP.NET路由可以不用映射到网站特定文件的URL.由于该 URL 不必映射到文件,因此可以使用对用户操作进行描述因而更易于被用户理解的 URL。.NET Framework 3.5 SP1已经包含了ASP.NET Routing引擎。现在微软已经在ASP.NET WebForms 4.0中增加了对Routing引擎更好的支持,它使用表达式构造器进行双向Routing。
    MVC 应用程序中的典型 URL 模式——来自MSDN

    MVC 应用程序中用于路由的 URL 模式通常包括 {controller} 和 {action} 占位符。

    当收到请求时,会将其路由到 UrlRoutingModule 对象,然后路由到 MvcHandler HTTP 处理程序。 MvcHandler HTTP 处理程序通过向 URL 中的控制器值添加后缀“Controller”以确定将处理请求的控制器的类型名称,来确定要调用的控制器。URL 中的操作值确定要调用的操作方法。

    MVC项目中添加路由,Global.asax 文件默认的MVC 路由的代码。

    默认配置:

     1 public static void RegisterRoutes(RouteCollection routes)
     2 {
     3     routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
     4     
     5     routes.MapRoute(
     6         "Default", // Route name
     7         "{controller}/{action}/{id}", // URL with parameters
     8         new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
     9     );
    10     
    11 }
    1 protected void Application_Start()
    2 {
    3     AreaRegistration.RegisterAllAreas();
    4     
    5     RegisterGlobalFilters(GlobalFilters.Filters);
    6     RegisterRoutes(RouteTable.Routes);
    7 }

    涉及类参考

    说明
    Route 表示 Web 窗体或 MVC 应用程序中的路由。
    RouteBase 用作表示 ASP.NET 路由的所有类的基类。
    RouteTable 存储应用程序的路由。
    RouteData 包含所请求路由的值。
    RequestContext 包含有关对应于路由的 HTTP 请求的信息。
    RouteValueDictionary 提供用于存储路由 Constraints、Defaults 和 DataTokens 对象的方法。
    VirtualPathData 提供用于从路由信息生成 URL 的方法。

    因为目前采用的是ASP.NET MVC 3进而可以利用扩展Route的方式实现。

    首先定义DomainData、DomainRoute类

    代码如下:

    DomainRoute类:

      1     public class DomainRoute : Route
      2     {
      3         private Regex domainRegex;
      4         private Regex pathRegex;
      5 
      6         public string Domain { get; set; }
      7 
      8         public DomainRoute(string domain, string url, RouteValueDictionary defaults)
      9             : base(url, defaults, new MvcRouteHandler())
     10         {
     11             Domain = domain;
     12         }
     13 
     14         public DomainRoute(string domain, string url, RouteValueDictionary defaults, IRouteHandler routeHandler)
     15             : base(url, defaults, routeHandler)
     16         {
     17             Domain = domain;
     18         }
     19 
     20         public DomainRoute(string domain, string url, object defaults)
     21             : base(url, new RouteValueDictionary(defaults), new MvcRouteHandler())
     22         {
     23             Domain = domain;
     24         }
     25 
     26         public DomainRoute(string domain, string url, object defaults, IRouteHandler routeHandler)
     27             : base(url, new RouteValueDictionary(defaults), routeHandler)
     28         {
     29             Domain = domain;
     30         }
     31 
     32         public override RouteData GetRouteData(HttpContextBase httpContext)
     33         {
     34             // 构造 regex
     35             domainRegex = CreateRegex(Domain);
     36             pathRegex = CreateRegex(Url);
     37 
     38             // 请求信息
     39             string requestDomain = httpContext.Request.Headers["host"];
     40             if (!string.IsNullOrEmpty(requestDomain))
     41             {
     42                 if (requestDomain.IndexOf(":") > 0)
     43                 {
     44                     requestDomain = requestDomain.Substring(0, requestDomain.IndexOf(":"));
     45                 }
     46             }
     47             else
     48             {
     49                 requestDomain = httpContext.Request.Url.Host;
     50             }
     51             string requestPath = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2) + httpContext.Request.PathInfo;
     52 
     53             // 匹配域名和路由
     54             Match domainMatch = domainRegex.Match(requestDomain);
     55             Match pathMatch = pathRegex.Match(requestPath);
     56 
     57             // 路由数据
     58             RouteData data = null;
     59             if (domainMatch.Success && pathMatch.Success)
     60             {
     61                 data = new RouteData(this, RouteHandler);
     62 
     63                 // 添加默认选项
     64                 if (Defaults != null)
     65                 {
     66                     foreach (KeyValuePair<string, object> item in Defaults)
     67                     {
     68                         data.Values[item.Key] = item.Value;
     69                         if (item.Key.Equals("area") || item.Key.Equals("namespaces"))
     70                         {
     71                             data.DataTokens[item.Key] = item.Value;
     72                         }
     73                     }
     74                 }
     75 
     76                 // 匹配域名路由
     77                 for (int i = 1; i < domainMatch.Groups.Count; i++)
     78                 {
     79                     Group group = domainMatch.Groups[i];
     80                     if (group.Success)
     81                     {
     82                         string key = domainRegex.GroupNameFromNumber(i);
     83 
     84                         if (!string.IsNullOrEmpty(key) && !char.IsNumber(key, 0))
     85                         {
     86                             if (!string.IsNullOrEmpty(group.Value))
     87                             {
     88                                 data.Values[key] = group.Value;
     89                                 if (key.Equals("area"))
     90                                 {
     91                                     data.DataTokens[key] = group.Value;
     92                                 }
     93                             }
     94                         }
     95                     }
     96                 }
     97 
     98                 // 匹配域名路径
     99                 for (int i = 1; i < pathMatch.Groups.Count; i++)
    100                 {
    101                     Group group = pathMatch.Groups[i];
    102                     if (group.Success)
    103                     {
    104                         string key = pathRegex.GroupNameFromNumber(i);
    105 
    106                         if (!string.IsNullOrEmpty(key) && !char.IsNumber(key, 0))
    107                         {
    108                             if (!string.IsNullOrEmpty(group.Value))
    109                             {
    110                                 data.Values[key] = group.Value;
    111                                 if (key.Equals("area"))
    112                                 {
    113                                     data.DataTokens[key] = group.Value;
    114                                 }
    115                             }
    116                         }
    117                     }
    118                 }
    119             }
    120 
    121             return data;
    122         }
    123 
    124         public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    125         {
    126             return base.GetVirtualPath(requestContext, RemoveDomainTokens(values));
    127         }
    128 
    129         //public DomainData GetDomainData(RequestContext requestContext, RouteValueDictionary values)
    130         //{
    131         //    // 获得主机名
    132         //    string hostname = Domain;
    133         //    foreach (KeyValuePair<string, object> pair in values)
    134         //    {
    135         //        hostname = hostname.Replace("{" + pair.Key + "}", pair.Value.ToString());
    136         //    }
    137 
    138         //    // Return 域名数据
    139         //    return new DomainData
    140         //    {
    141         //        Protocol = "http",
    142         //        HostName = hostname,
    143         //        Fragment = ""
    144         //    };
    145         //}
    146 
    147         private Regex CreateRegex(string source)
    148         {
    149             // 替换
    150             source = source.Replace("/", @"/?");
    151             source = source.Replace(".", @".?");
    152             source = source.Replace("-", @"-?");
    153             source = source.Replace("{", @"(?<");
    154             source = source.Replace("}", @">([a-zA-Z0-9_]*))");
    155 
    156             return new Regex("^" + source + "$");
    157         }
    158 
    159         private RouteValueDictionary RemoveDomainTokens(RouteValueDictionary values)
    160         {
    161             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_]*})*-?.?/?");
    162             Match tokenMatch = tokenRegex.Match(Domain);
    163             for (int i = 0; i < tokenMatch.Groups.Count; i++)
    164             {
    165                 Group group = tokenMatch.Groups[i];
    166                 if (group.Success)
    167                 {
    168                     string key = group.Value.Replace("{", "").Replace("}", "");
    169                     if (values.ContainsKey(key))
    170                         values.Remove(key);
    171                 }
    172             }
    173 
    174             return values;
    175         }
    176     }
    View Code

    然后注册我的产品管理系统

    并且注册区域路由规则

     1     public class BlockAreaRegistration : AreaRegistration
     2     {
     3         public override string AreaName
     4         {
     5             get
     6             {
     7                 return "Block";
     8             }
     9         }
    10 
    11         public override void RegisterArea(AreaRegistrationContext context)
    12         {
    13             context.Routes.Add(new DomainRoute(
    14                "us.block.com",     // Domain with parameters 需要配置host文件 
    15                "{controller}/{action}/{id}",    // URL with parameters 
    16                new
    17                {
    18                    area = "Block",
    19                    controller = "Default",
    20                    action = "Index",
    21                    id = UrlParameter.Optional,
    22                    namespaces = new[] { "Notify.Solution.WebMvc.Areas.Block.Controllers" }
    23                }));
    24         }
    25     }
    View Code

    当用户访问www.Block.com 时候就会访问主站点

    当用户访问us.Block.com 时候就会访问二级域名站点

  • 相关阅读:
    JS reduce方法的使用
    面试娱录
    sticky置顶功能影响了锚点定位
    postcss-px-to-viewport移动端自适应
    axios请求参数自动拼接到了地址那里
    ping 不通。无法访问目标主机
    JS前后台方法的相互调用
    SQL server2008 无法连接服务器
    Assembly.Load未能加载文件或程序集“”或它的某一个依赖项。系统找不到指定的文件
    JS判断IE和非IE
  • 原文地址:https://www.cnblogs.com/liuxiaoji/p/4576681.html
Copyright © 2011-2022 走看看