Asp.net-Mvc-5

MVC5 中的域路由

  • November 4, 2016

我意識到有幾篇關於類似事情的文章,但沒有一篇對我有幫助。

我有一個 Web 應用程序,其中有多個域指向同一個應用程序。我想知道如何根據嘗試訪問 Web 應用程序的域將路由映射到特定控制器。

我目前嘗試的是以下沒有成功。

routes.MapRoute(
   name: "WowPoetry",
   url: "wowpoetry.org/{action}/{id}",
   defaults: new { controller = "Wow", action = "Index", id = UrlParameter.Optional }
);

我最終按照本教程來實現我想要的,除了我以前做域路由而不是子域路由。

域路由教程 ASP.Net MVC

執行:

routes.Add(new DomainRoute("wowpoetry.org", "", new { controller = "Wow", action = "Index" }));

域數據.cs

public class DomainData
{
   public string Protocol { get; set; }
   public string HostName { get; set; }
   public string Fragment { get; set; }
}

域路由.cs

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)
   {
       // Build regex
       domainRegex = CreateRegex(Domain);
       pathRegex = CreateRegex(Url);

       // Request information
       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 domain and route
       Match domainMatch = domainRegex.Match(requestDomain);
       Match pathMatch = pathRegex.Match(requestPath);

       // Route data
       RouteData data = null;
       if (domainMatch.Success && pathMatch.Success && requestDomain.ToLower() != "tg.local" &&
           requestDomain.ToLower() != "tg.terrasynq.net" && requestDomain.ToLower() != "www.townsgossip.com" &&
           requestDomain.ToLower() != "townsgossip.com")
       {
           data = new RouteData(this, RouteHandler);

           // Add defaults first
           if (Defaults != null)
           {
               foreach (KeyValuePair<string, object> item in Defaults)
               {
                   data.Values[item.Key] = item.Value;
               }
           }

           // Iterate matching domain groups
           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;
                       }
                   }
               }
           }

           // Iterate matching path groups
           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)
   {
       // Build hostname
       string hostname = Domain;
       foreach (KeyValuePair<string, object> pair in values)
       {
           hostname = hostname.Replace("{" + pair.Key + "}", pair.Value.ToString());
       }

       // Return domain data
       return new DomainData
       {
           Protocol = "http",
           HostName = hostname,
           Fragment = ""
       };
   }

   private Regex CreateRegex(string source)
   {
       // Perform replacements
       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)
   {
       var 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;
   }
}

引用自:https://stackoverflow.com/questions/28644293