会社の仕事の都合で、他のテクノロジーを勉強していたため、ブログを更新する時間がありませんでしたが、今日はやっと仕事をやめて、新しいコンテンツを書くことができます。
アプリケーションシナリオ: 企業ポータルは、Sina にはスポーツ、エンターテイメントチャンネルなど、さまざまなコンテンツに応じてさまざまなセクションが設定されます。場合によっては、Sina Sports sports.sina.com.cn など、セクションごとに異なる第 2 レベルのドメイン名を設定する必要があります。
asp.net core mvc では、セクションの効果を実現したい場合、セクションごとに異なるコントローラーを作成できます (もちろん、他のテクノロジもあります。実装の品質についてはここでは説明しません)。この場合、たとえば、スポーツ コントローラを介してシステムにアクセスする場合、スポーツ チャネルに対応するコントローラは、SportController と呼ばれます。
上記のシナリオについて説明したので、それを実装する方法を見てみましょう。
asp.net core mvc にはルーティング ルールの設定があります。設定場所は Startup.Configure メソッド内にあります。具体的なコードは次のとおりです。
app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}", defaults: new { area="admin"}); });
残念ながら、ドメイン名のサポートはサポートされていません。現在私は であると理解しています。質問がある場合は修正してください)。 Router.MapRouter を通じてルーティング ルールを登録し、それらを RouteCollection に追加します。 リクエストが届くと、最初に一致する IRouter が見つかるまで、RouterCollection は登録されているすべての IRouter オブジェクトをループします。フレームワークはドメイン名設定ルールをサポートしていませんが、第 2 レベルのドメイン名決定ロジックを実装するために IRouter を実装することができます。具体的な実装コードは次のとおりです。上のコードではドメイン名の検出のみを確認しましたが、ドメイン名を特定のコントローラーに送信するには、この IRouter を登録するときにいくつかの記事を実行し、コードを直接入力する必要があります:
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); } }
最後に、対応するものを登録できます。 in Startup ルールは次のとおりです:
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; } }
実装方法は最善ではないかもしれませんが、基本的なニーズは満たしています。より良い方法がある場合は、議論して交換することを歓迎します。
以上がasp.net core mvc で第 2 レベルのドメイン名を特定のコントローラーにバインドする方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。