Subdominios dinámicos en asp.net mvc
-
10-07-2019 - |
Pregunta
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 el contenido que se muestra.
Ejemplo:
user1subdomain.mydomain.com/Whatever
user2subdomain.mydomain.com/Whatever
Ambos usarán 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 sea lo suficientemente flexible como para que se puedan agregar nuevos subdominios a la base de datos sin tener que volver a escribir las reglas de enrutamiento cada vez que se agrega un nuevo subdominio.
Solución
MVC no está vinculado al dominio, solo a la ruta (por ejemplo, http: // dominio / ruta ).
Para hacer esto correctamente, necesita lo siguiente ...
- Configuración de DNS comodín para * .yourdomain.com apunta a su servidor.
- El sitio en la configuración de IIS con sin encabezado de host. Cualquier otro sitio alojado en esa instancia de IIS en la misma IP debe tener encabezados de host especificado.
- Su aplicación deberá verificar el solicitar el encabezado del host en la carga de la página inicio de sesión o algún otro evento.
Otros consejos
Encontré una respuesta más fácil en el blog de esta persona. Muy sorprendido, esto funciona tan bien como lo hace y que 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 de 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 así es como se puede usar.
routes.Add("DomainRoute", new DomainRoute(
"{controller}-{action}.example.com", // Domain with parameters
"{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
));
Principalmente no es un problema. ¡Creo!
En términos de la aplicación / enrutamiento, el enrutamiento comienza donde termina el dominio, por lo que asignar múltiples dominios a la misma aplicación no es un problema, eso simplemente funcionará.
En términos de IIS, puede asignar tantos dominios como desee (bueno, seguramente habrá un límite) a un solo sitio. No estoy seguro de si puede usar un comodín. ¿Qué versión de IIS está usando?
Cuando llega una solicitud, hay eventos que puede conectar para ver el dominio y, por lo tanto, configurar los parámetros que desee (usuario, por ejemplo), la URL raíz de la solicitud también está disponible en el contexto más adelante en el ciclo, pero usted querrá recogerlo temprano.
Si puede hacer comodines, se vuelve bastante trivial: recoja la solicitud, valide el subdominio con los usuarios de la base de datos (si no es válida la redirección al sitio predeterminado), configure el usuario y continúe con el enrutamiento normal.
Si no puede hacer comodines, entonces 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.