244 votes

Est il possible de faire un itinéraire ASP.NET MVC basé sur un sous-domaine ?

Est-il possible d’avoir un itinéraire ASP.NET MVC qui utilise les informations de sous-domaine pour déterminer son itinéraire ? Par exemple :

  • User1. domaine.com va à un seul endroit
  • User2. domaine.com passe à l’autre ?

Ou, puis-je le faire afin que ces deux arrivent à la même contrôleur/action avec un `` paramètre ?

170voto

Jon Cahill Points 2516

Vous pouvez le faire en créant un nouvel itinéraire et en ajoutant à la collection d’itinéraires dans RegisterRoutes dans votre global.asax. Voici un exemple très simple d’un itinéraire personnalisé :

55voto

Edward Brey Points 8771

Pour capturer le sous-domaine tout en conservant la norme MVC5 des fonctionnalités de routage, utilisez la commande suivante SubdomainRoute classe dérivée de l' Route.

En outre, SubdomainRoute permet le sous-domaine éventuellement être spécifié comme paramètre de requête, rendant sub.example.com/foo/bar et example.com/foo/bar?subdomain=sub équivalent. Cela vous permet de tester avant de les sous-domaines DNS sont configurés. Le paramètre de requête (lorsqu'en service) est multiplié par le biais de nouveaux liens générés par Url.Action, etc.

Le paramètre de requête permet également de débogage locale avec Visual Studio 2013, sans avoir à configurer avec netsh ou exécuter en tant qu'Administrateur. Par défaut, IIS Express ne lie localhost lorsque la non-élevée; il ne se lient pas à la synonymes de noms d'hôtes comme sous.localtest.moi.

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é, appeler le MapSubdomainRoute méthode de votre RegisterRoutes méthode, comme vous le feriez plaine vieux - 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 aux sous-domaine (que ce soit à partir d'un vrai sous-domaine ou un paramètre de requête), il est utile de créer un Contrôleur de la classe de base avec cette Subdomain de la propriété:

protected string Subdomain
{
    get { return (string)Request.RequestContext.RouteData.Values["subdomain"]; }
}

23voto

Jim Blake Points 707

Ce n’est pas mon travail, mais j’ai dû ajouter sur cette réponse.

Voici une excellente solution à ce problème. Maartin Balliauw a écrit le code qui crée une classe DomainRoute qui peut être utilisé très similaire à la gamme normale.

http://blog.maartenballiauw.be/post/2009/05/20/ASPNET-MVC-Domain-Routing.aspx

Utilisation de l’échantillon serait comme ça...

;

4voto

Edward Brey Points 8771

Pour capturer le sous-domaine lors de l'utilisation de l'API Web, remplacer l'Action Sélecteur d'injecter un subdomain paramètre de requête. Ensuite, utiliser le sous-domaine paramètre de requête dans vos controllers' actions comme ceci:

public string Get(string id, string subdomain)

Cette approche rend le débogage pratique car vous pouvez spécifier le paramètre de requête à la main lors de l'utilisation de localhost au lieu du nom de l'hôte (voir le standard MVC5 de routage réponse pour plus de détails). Ceci est le code de l'Action Sélecteur:

class SubdomainActionSelector : IHttpActionSelector
{
    private readonly IHttpActionSelector defaultSelector;

    public SubdomainActionSelector(IHttpActionSelector defaultSelector)
    {
        this.defaultSelector = defaultSelector;
    }

    public ILookup<string, HttpActionDescriptor> GetActionMapping(HttpControllerDescriptor controllerDescriptor)
    {
        return defaultSelector.GetActionMapping(controllerDescriptor);
    }

    public HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
    {
        var routeValues = controllerContext.Request.GetRouteData().Values;
        if (!routeValues.ContainsKey("subdomain")) {
            string host = controllerContext.Request.Headers.Host;
            int index = host.IndexOf('.');
            if (index >= 0)
                controllerContext.Request.GetRouteData().Values.Add("subdomain", host.Substring(0, index));
        }
        return defaultSelector.SelectAction(controllerContext);
    }
}

Remplacer l'Action par défaut Sélecteur par l'ajout de ce WebApiConfig.Register:

config.Services.Replace(typeof(IHttpActionSelector), new SubdomainActionSelector(config.Services.GetActionSelector()));

3voto

Nick Berardi Points 31361

Oui, mais vous devez créer votre propre gestionnaire d’itinéraire.

En général, la voie n’est pas au courant du domaine parce que l’application pourrait être déployée à n’importe quel domaine et de la route ne soigneraient pas une manière ou une autre. Mais dans votre cas vous souhaitez baser le contrôleur et une action contre le domaine, alors vous devrez créer un itinéraire personnalisé qui est au courant du domaine.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X