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"}); });
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); } }
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; } }
app.UseMvc( routes => { routes.MapDomainRoute("xxx.domain.com","areaname","controllername"); routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}", defaults: new { area = "web" }); });
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!