Maison  >  Article  >  développement back-end  >  Tutoriel sur la liaison d'un nom de domaine de deuxième niveau à une instance de contrôleur spécifique

Tutoriel sur la liaison d'un nom de domaine de deuxième niveau à une instance de contrôleur spécifique

零下一度
零下一度original
2017-06-17 10:24:081510parcourir

Cet article présente principalement comment lier le nom de domaine de deuxième niveau à un contrôleur spécifique dans Asp.net Core MVC. Les amis qui en ont besoin peuvent s'y référer

.

Scénarios d'application : les portails d'entreprise créeront différentes sections en fonction de différents contenus, tels que Sina propose des chaînes de sport, de divertissement, etc. Dans certains cas, il est nécessaire de créer différents noms de domaine de deuxième niveau pour différentes sections, comme Sina Sports sports.sina.com.cn.

Dans asp.net core mvc, si vous souhaitez obtenir l'effet de sections, vous pouvez créer différents contrôleurs pour différentes sections (bien sûr il existe d'autres technologies, la qualité de l'implémentation n'est pas discutée ici), Dans ce cas, comment lier un nom de domaine unique de deuxième niveau au contrôleur. Par exemple, le contrôleur correspondant à la chaîne sportive s'appelle SportController. Lorsque vous accédez au système via le nom de domaine sports.XXX.com, saisissez directement le nom de domaine. SportController et transmettez ce nom de domaine de deuxième niveau. Le nom de domaine ne peut pas accéder aux autres contrôleurs.

Maintenant que nous avons fini de parler du scénario, voyons comment le mettre en œuvre.

Il existe une configuration de règle de routage dans asp.net core mvc. La configuration est dans la méthode Startup.Configure. Le code spécifique est le suivant :


.
app.UseMvc(routes =>
{
   routes.MapRoute(
      name: "default",
      template: "{controller=Home}/{action=Index}/{id?}",
      defaults: new { area="admin"});
});

Malheureusement, il ne prend pas en charge les noms de domaine (ce que j'ai compris jusqu'à présent, c'est que s'il y a des problèmes, vous pouvez me corriger). Enregistrez les règles de routage via routes.MapRouter et ajoutez-les à RouteCollection Lorsqu'une demande arrive, RouterCollection parcourt tous les objets IRouter enregistrés jusqu'à ce que le premier IRouter correspondant soit trouvé. Bien que le framework ne prenne pas en charge les règles de configuration des noms de domaine, nous pouvons implémenter nous-mêmes un IRouter pour implémenter la logique de jugement des noms de domaine de deuxième niveau. Je l'ai temporairement nommé SubDomainRouter. Le code d'implémentation spécifique est le suivant :

<.>

public class SubDomainRouter : RouteBase
 {
   private readonly IRouter _target;
   private readonly string _subDomain;
   public SubDomainRouter(
     IRouter target,
     string subDomain,//当前路由规则绑定的二级域名
     string routeTemplate,
     RouteValueDictionary defaults,
     RouteValueDictionary constrains,
     IInlineConstraintResolver inlineConstraintResolver)
     : base(routeTemplate,
        subDomain,
        inlineConstraintResolver,
        defaults,
        constrains,
        new RouteValueDictionary(null))
   {
     if (target == null)
     {
       throw new ArgumentNullException(nameof(target));
     }
     if (subDomain == null)
     {
       throw new ArgumentNullException(nameof(subDomain));
     }
     _subDomain = subDomain;
     _target = target;
   }
   public override Task RouteAsync(RouteContext context)
   {
     string domain = context.HttpContext.Request.Host.Host;//获取当前请求域名,然后跟_subDomain比较,如果不想等,直接忽略
     if (string.IsNullOrEmpty(domain) || string.Compare(_subDomain, domain) != 0)
     {
       return Task.CompletedTask;
     }
      
     //如果域名匹配,再去验证访问路径是否匹配
     return base.RouteAsync(context);
   }
   protected override Task OnRouteMatched(RouteContext context)
   {
     context.RouteData.Routers.Add(_target);
     return _target.RouteAsync(context);
   }
   protected override VirtualPathData OnVirtualPathGenerated(VirtualPathContext context)
   {
     return _target.GetVirtualPath(context);
   }
 }
À partir du code ci-dessus, nous ne voyons que la détection du nom de domaine, mais comment diriger le nom de domaine vers un contrôleur spécifique nous oblige à effectuer un certain travail lors de l'enregistrement de cet IRouter et à saisir directement le code :


public static class RouteBuilderExtensions
  {    public static IRouteBuilder MapDomainRoute(
      this IRouteBuilder routeBuilder,string domain,string area,string controller)
    {
      if(string.IsNullOrEmpty(area)||string.IsNullOrEmpty(controller))
      {
        throw new ArgumentNullException("area or controller can not be null");
      }
      var inlineConstraintResolver = routeBuilder
        .ServiceProvider
        .GetRequiredService<IInlineConstraintResolver>();
        string template = "";
          RouteValueDictionary defaults = new RouteValueDictionary();
          RouteValueDictionary constrains = new RouteValueDictionary();
          constrains.Add("area", area);
          defaults.Add("area", area);
          constrains.Add("controller", controller);
          defaults.Add("controller", string.IsNullOrEmpty(controller) ? "home" : controller);
          defaults.Add("action", "index");
          template += "{action}/{id?}";//路径规则中不再包含控制器信息,但是上面通过constrains限定了查找时所要求的控制器名称
          routeBuilder.Routes.Add(new SubDomainRouter(routeBuilder.DefaultHandler, domain, template, defaults, constrains, inlineConstraintResolver));
      return routeBuilder;
    }
}
Enfin nous pouvons enregistrer les règles correspondantes dans Startup, comme suit :


Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn