2015-02-21 11 views
5

Ich weiß, es gibt ein paar Artikel über ähnliche Dinge, aber keiner von denen hat mir geholfen.Domain Routing in MVC5

Ich habe eine einzelne Web-App mit mehreren Domains auf die gleiche App zeigen. Ich würde gerne wissen, wie ich eine Route zu einem bestimmten Controller zuordnen kann, basierend auf der Domäne, die versucht, auf die Web-App zuzugreifen.

Was ich derzeit versucht, ist das folgende ohne Erfolg.

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

Antwort

8

landete ich nach dieser Anleitung bis zu erreichen, was ich mit der Ausnahme, wollte ich verwenden, um Domain-Routing und nicht Sub-Domain-Routing zu tun.

Domain Routing Tutorial ASP.Net MVC

Umsetzung:

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

DomainData.cs

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

DomainRoute.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; 
    } 
}