2009-11-30 103 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 
));