Pour capturer le sous-domaine tout en conservant les fonctionnalités de routage MVC5 standard , utilisez la SubdomainRouteclasse suivante dérivée de Route.
En outre, SubdomainRoutepermet éventuellement de spécifier le sous-domaine en tant que paramètre de requête , faisant sub.example.com/foo/baret example.com/foo/bar?subdomain=subéquivalent. Cela vous permet de tester avant de configurer les sous-domaines DNS. Le paramètre de requête (lorsqu'il est utilisé) est propagé via de nouveaux liens générés par Url.Action, etc.
Le paramètre de requête permet également le débogage local avec Visual Studio 2013 sans avoir à configurer avec netsh ou à exécuter en tant qu'administrateur . Par défaut, IIS Express ne se lie à localhost que lorsqu'il n'est pas élevé; il ne se liera pas aux noms d'hôte comme sub.localtest.me .
class SubdomainRoute : Route
{
public SubdomainRoute(string url) : base(url, new MvcRouteHandler()) {}
public override RouteData GetRouteData(HttpContextBase httpContext)
{
var routeData = base.GetRouteData(httpContext);
if (routeData == null) return null; // Only look at the subdomain if this route matches in the first place.
string subdomain = httpContext.Request.Params["subdomain"]; // A subdomain specified as a query parameter takes precedence over the hostname.
if (subdomain == null) {
string host = httpContext.Request.Headers["Host"];
int index = host.IndexOf('.');
if (index >= 0)
subdomain = host.Substring(0, index);
}
if (subdomain != null)
routeData.Values["subdomain"] = subdomain;
return routeData;
}
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
object subdomainParam = requestContext.HttpContext.Request.Params["subdomain"];
if (subdomainParam != null)
values["subdomain"] = subdomainParam;
return base.GetVirtualPath(requestContext, values);
}
}
Pour plus de commodité, appelez la MapSubdomainRouteméthode suivante à partir de votre RegisterRoutesméthode, comme vous le feriez tout simplement MapRoute:
static void MapSubdomainRoute(this RouteCollection routes, string name, string url, object defaults = null, object constraints = null)
{
routes.Add(name, new SubdomainRoute(url) {
Defaults = new RouteValueDictionary(defaults),
Constraints = new RouteValueDictionary(constraints),
DataTokens = new RouteValueDictionary()
});
}
Enfin, pour accéder facilement au sous-domaine (à partir d'un vrai sous-domaine ou d'un paramètre de requête), il est utile de créer une classe de base Controller avec cette Subdomainpropriété:
protected string Subdomain
{
get { return (string)Request.RequestContext.RouteData.Values["subdomain"]; }
}