Maison > développement back-end > Tutoriel C#.Net > Comment lier le nom de domaine de deuxième niveau à un contrôleur spécifique dans asp.net core mvc

Comment lier le nom de domaine de deuxième niveau à un contrôleur spécifique dans asp.net core mvc

巴扎黑
Libérer: 2017-06-26 15:19:42
original
1547 Les gens l'ont consulté

En raison des modalités de travail de l'entreprise, j'ai étudié d'autres technologies, je n'ai donc pas eu le temps de mettre à jour le blog. Aujourd'hui, je peux enfin arrêter ce que je fais et écrire du nouveau contenu.

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 définir 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"});
});
Copier après la connexion
.

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);
        }
    }
Copier après la connexion
À 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 à accéder directement au 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;
        }
}
Copier après la connexion
Enfin, nous pouvons enregistrer les règles correspondantes dans Startup, comme suit :

app.UseMvc(
      routes =>
        {
            routes.MapDomainRoute("xxx.domain.com","areaname","controllername");
                        
            routes.MapRoute(
                  name: "default",
                  template: "{controller=Home}/{action=Index}/{id?}",
                  defaults: new { area = "web" });
        });
Copier après la connexion
La méthode de mise en œuvre n'est peut-être pas la meilleure, mais c'est déjà le cas. Cela répond aux besoins fondamentaux. Si vous avez une meilleure méthode, vous êtes invités à en discuter et à l'échanger.

 

 

 

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!

source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal