회사의 업무 일정으로 인해 다른 기술을 공부하고 있어서 블로그를 업데이트할 시간이 없었습니다. 오늘 드디어 하던 일을 멈추고 새로운 콘텐츠를 작성할 수 있게 되었습니다.
적용 시나리오: 기업 포털은 Sina의 스포츠, 엔터테인먼트 채널 등 다양한 콘텐츠에 따라 다양한 섹션을 설정합니다. 어떤 경우에는 Sina Sports sports.sina.com.cn과 같이 섹션마다 다른 2차 도메인 이름을 설정해야 합니다.
asp.net 코어 mvc에서 섹션의 효과를 얻으려면 섹션마다 다른 컨트롤러를 만들 수 있습니다(물론 다른 기술도 있으므로 구현 품질은 여기서 논의하지 않습니다). 예를 들어 스포츠 컨트롤러를 통해 시스템에 액세스하는 경우 스포츠 채널에 해당하는 컨트롤러를 컨트롤러에 바인딩하는 방법입니다.
이제 위의 시나리오에 대해 설명했으니 구현 방법을 살펴보겠습니다.
asp.net 코어 mvc에 라우팅 규칙 구성이 있습니다. 구성 위치는 Startup.Configure 메서드에 있습니다. 구체적인 코드는 다음과 같습니다.
app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}", defaults: new { area="admin"}); });
안타깝게도 도메인 이름 지원은 지원되지 않습니다. 현재 이해하고 있는 내용은 입니다. 질문이 있으면 정정해 주세요). RouteCollection을 통해 라우팅 규칙을 등록하고 RouteCollection에 추가합니다. 요청이 오면 RouterCollection은 일치하는 첫 번째 IRouter를 찾을 때까지 등록된 모든 IRouter 개체를 반복합니다. 프레임워크는 도메인 이름 구성 규칙을 지원하지 않지만 IRouter를 직접 구현하여 2차 도메인 이름 결정 논리를 구현할 수 있습니다. 임시로 이름을 SubDomainRouter로 지정했습니다.
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); } }
위의 코드에서는 도메인 이름 감지만 보았지만 도메인 이름을 특정 컨트롤러로 지정하려면 이 IRouter를 등록할 때 몇 가지 기사를 수행하고 코드를 직접 입력해야 합니다.
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; } }
마지막으로 해당 컨트롤러를 등록할 수 있습니다. in Startup 규칙은 다음과 같습니다.
app.UseMvc( routes => { routes.MapDomainRoute("xxx.domain.com","areaname","controllername"); routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}", defaults: new { area = "web" }); });
구현 방법이 최고는 아닐 수 있지만 기본 요구 사항을 충족했습니다. 더 나은 방법이 있으면 토론하고 교환할 수 있습니다.
위 내용은 asp.net core mvc의 특정 컨트롤러에 두 번째 수준 도메인 이름을 바인딩하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!