2009-11-30 68 views
10

我对asp.net相当陌生,对iis几乎没有经验。我希望我的应用程序的每个用户都有自己的子域,但都使用相同的控制器。子域然后将控制显示的内容。asp.net中的动态子域名mvc

实施例:

user1subdomain.mydomain.com/Whatever 
user2subdomain.mydomain.com/Whatever 

都将使用相同的控制器。理想情况下,参数可以将用户名赋予控制器,然后控制器可以显示适当的内容。我希望它足够灵活,以便在每次添加新子域时都可以在不重写路由规则的情况下将新的子域添加到数据库中。

+0

我实际上到目前为止只使用内置的visual studio服务器,所以域是localhost。我不能让任何subdomain.localhost /不管把我弄一个有效的控制器都还没有。 – captncraig 2009-11-30 21:20:11

+0

你不会与本地主机 - 要测试的域名管理方面,你必须跑起来IIS。 – Murph 2009-12-01 08:23:18

回答

9

MVC未绑定到域,仅限于路径(例如http://domain/path)。

要为 都是这么做的,你需要以下...

  1. 通配符DNS设置* .yourdomain.com指向你的服务器。
  2. IIS设置中的站点使用 没有主机头。任何其他网站 承载在该实例的IIS 相同的IP必须具有指定的主机标头 。
  3. 您的应用程序需要在页面加载, 会话启动或某些其他事件中检查 请求主机标头。
1

大都不是问题。我认为!

就应用程序/路由而言,路由在域结束的地方开始,因此将多个域映射到相同的应用程序不是问题,这只会起作用。

就IIS而言,您可以根据需要映射尽可能多的域名(当然这只限于一个站点) - 我不确定您是否可以使用通配符 - 您使用的是哪个版本的IIS ?

当请求到达时,您可以勾选以查看域并因此设置所需参数(例如用户)的事件,该请求的根URL也可以在周期的稍后的环境中使用 - 但你会想早点接受它。

如果你可以做通配符,它​​变得相当平凡 - 拿起请求,验证子数据库对数据库中的用户(如果不是有效的重定向到默认站点),设置用户并继续通过正常路由。

如果你不能做通配符,那么当用户被添加到数据库时,挑战是从应用程序中随时添加主机头到IIS应用程序(网站)。

+2

在IIS如果一个主机头值没有为网站指定,那么它接受所有的主机头值,你只需要确保你只需要每IP设置1个网站,在IIS中的这种方式。 – MyItchyChin 2009-11-30 20:13:39

3

我在这个人的博客找到了一个更容易的答案。非常惊讶这个作品以及它的作用,并且这个解决方案已经超过4年了。

http://blog.maartenballiauw.be/post/2009/05/20/aspnet-mvc-domain-routing.aspx

定制路线的实现:

public class DomainRoute : Route 
{ 
    public string Domain { get; set; } 


    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) 
     { 
      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 = "" 
     }; 
    }} 

这里是它如何被使用。

routes.Add("DomainRoute", new DomainRoute(
"{controller}-{action}.example.com",  // Domain with parameters 
"{id}", // URL with parameters 
new { controller = "Home", action = "Index", id = "" } // Parameter defaults 
));