Per acquisire il sottodominio mantenendo le funzionalità di routing MVC5 standard , utilizzare la seguente SubdomainRouteclasse derivata Route.
Inoltre, SubdomainRouteconsente facoltativamente di specificare il sottodominio come parametro di query , di fabbricazione sub.example.com/foo/bare example.com/foo/bar?subdomain=subequivalente. Ciò consente di eseguire il test prima di configurare i sottodomini DNS. Il parametro di query (quando in uso) viene propagato attraverso nuovi collegamenti generati da Url.Action, ecc.
Il parametro query abilita anche il debug locale con Visual Studio 2013 senza dover configurare con netsh o eseguire come amministratore . Per impostazione predefinita, IIS Express si lega a localhost solo se non elevato; non si legherà a nomi host come 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);
}
}
Per comodità, chiama il seguente MapSubdomainRoutemetodo dal tuo RegisterRoutesmetodo come faresti con il vecchio 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()
});
}
Infine, per accedere comodamente al sottodominio (da un sottodominio vero o da un parametro di query), è utile creare una classe base del controller con questa Subdomainproprietà:
protected string Subdomain
{
get { return (string)Request.RequestContext.RouteData.Values["subdomain"]; }
}