2009-11-30 33 views
10

Soy bastante nuevo en asp.net, y tengo poca experiencia con iis. Me gustaría que cada usuario de mi aplicación obtenga su propio subdominio, pero todos usan los mismos controladores. El subdominio controlaría entonces qué contenido se muestra.Subdominios dinámicos en asp.net mvc

Ejemplo:

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

los dos para utilizar el mismo controlador. Idealmente, un parámetro podría dar el nombre de usuario al controlador, que luego podría mostrar el contenido apropiado. Me gustaría que fuera lo suficientemente flexible como para agregar nuevos subdominios a la base de datos sin reescribir las reglas de enrutamiento cada vez que se agrega un nuevo subdominio.

+0

Hasta ahora solo he estado utilizando el servidor visual studio incorporado, por lo que el dominio es localhost. No puedo obtener ningún subdomain.localhost/Lo que sea que me lleve a un controlador válido. – captncraig

+0

No lo hará con localhost: para probar los aspectos de administración de dominio, deberá ejecutar IIS. – Murph

Respuesta

9

MVC no está vinculado al dominio, solo a la ruta (por ejemplo, http://domain/path).

Para hacer esto correctamente es necesario lo siguiente ...

  1. configuración DNS para Comodín * .sudominio.com apuntando a su servidor.
  2. El sitio en la configuración de IIS con sin encabezado de host. Cualquier otro sitio alojado en esa instancia de IIS en , el mismo IP debe tener los encabezados Host especificados.
  3. Su aplicación tendrá que comprobar la cabecera petición de ordenador, ya sea al cargar la página, inicio de la sesión o algún otro evento.
1

La mayoría no es un problema. ¡Creo!

En términos de la aplicación/ROUTING el encaminamiento comienza donde el dominio extremos para la cartografía de dominios múltiples para la misma solicitud no es un problema, que se acaba de trabajar.

En términos de IIS, puede asignar tantos dominios como desee (bueno, debe haber un límite) a un único sitio, no estoy seguro si puede usar un comodín, ¿qué versión de IIS está utilizando? ?

Cuando llega una solicitud hay eventos que puede enganchar para mirar el dominio y configurar los parámetros que desea (por ejemplo, usuario), la URL raíz para la solicitud también está disponible en el contexto más adelante en el ciclo, pero querrás recogerlo temprano.

Si puede hacer comodines se vuelve bastante trivial - recoger la solicitud, validar el subdominio en contra de los usuarios en la base de datos (si no redireccionamiento válida para el sitio predeterminado), establece el usuario y continuar a través de la ruta normal.

Si no puede hacer comodines, el desafío es agregar encabezados de host a la aplicación IIS (sitio web) sobre la marcha desde su aplicación a medida que los usuarios se agregan a la base de datos.

+2

Con IIS si no se especifica un valor de encabezado de host para un sitio, entonces acepta todos los valores de encabezado de host, solo tiene que asegurarse de tener solo 1 sitio por configuración de IP en IIS de esta manera. – MyItchyChin

3

encontré una respuesta más fácil en el blog de esta persona. Muy sorprendido, esto funciona tan bien como funciona y esta solución tiene más de 4 años.

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

Una implementación ruta personalizada:

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

Y aquí es cómo se puede utilizar.

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