Heim > Backend-Entwicklung > C#.Net-Tutorial > So binden Sie den Domänennamen der zweiten Ebene an einen bestimmten Controller in asp.net core mvc

So binden Sie den Domänennamen der zweiten Ebene an einen bestimmten Controller in asp.net core mvc

巴扎黑
Freigeben: 2017-06-26 15:19:42
Original
1556 Leute haben es durchsucht

Aufgrund der Arbeitsvereinbarungen des Unternehmens habe ich mich mit anderen Technologien beschäftigt, sodass ich keine Zeit hatte, den Blog zu aktualisieren. Heute kann ich endlich mit meiner Arbeit aufhören und neue Inhalte schreiben.

Anwendungsszenarien: Unternehmensportale richten unterschiedliche Abschnitte entsprechend unterschiedlichen Inhalten ein, z. B. Sina verfügt über Sport-, Unterhaltungskanäle usw. In einigen Fällen ist es erforderlich, für verschiedene Abschnitte unterschiedliche Second-Level-Domainnamen festzulegen, z. B. Sina Sports sports.sina.com.cn.

Wenn Sie in asp.net core mvc den Effekt von Abschnitten erzielen möchten, können Sie unterschiedliche Controller für verschiedene Abschnitte erstellen (natürlich gibt es auch andere Technologien, die Qualität der Implementierung wird hier nicht besprochen). in diesem Fall, wie man einen eindeutigen Domänennamen der zweiten Ebene an den Controller bindet. Beispielsweise heißt der Controller, der dem Sportkanal entspricht, beim Zugriff auf das System über den Domänennamen sports.XXX.com SportController und übergeben Sie diesen Domänennamen der zweiten Ebene. Der Domänenname kann nicht auf andere Controller zugreifen.

Nachdem wir nun über das Szenario gesprochen haben, werfen wir einen Blick auf die Umsetzung.

Es gibt eine Routing-Regelkonfiguration in asp.net core mvc. Die Konfiguration befindet sich in der Startup.Configure-Methode. Der spezifische Code lautet wie folgt:

 

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

Leider werden keine Domain-Namen unterstützt (was ich bisher verstanden habe ist, dass Sie mich bei Problemen gerne korrigieren können). Registrieren Sie Routing-Regeln über „routes.MapRouter“ und fügen Sie sie zu „RouteCollection“ hinzu. Wenn eine Anfrage eingeht, durchläuft RouterCollection alle registrierten IRouter-Objekte, bis der erste passende IRouter gefunden wird. Obwohl das Framework keine Domänennamen-Konfigurationsregeln unterstützt, können wir einen IRouter selbst implementieren, um die Logik der Domänennamenbeurteilung der zweiten Ebene zu implementieren. Der spezifische Implementierungscode lautet wie folgt:

  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);
        }
    }
Nach dem Login kopieren

Im obigen Code sehen wir nur die Erkennung von Domänennamen, aber um den Domänennamen an einen bestimmten Controller weiterzuleiten, müssen wir bei der Registrierung dieses IRouters etwas Arbeit leisten und direkt zum Code gehen:

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;
        }
}
Nach dem Login kopieren

Schließlich können wir die entsprechenden Regeln im Startup registrieren, wie folgt:

app.UseMvc(
      routes =>
        {
            routes.MapDomainRoute("xxx.domain.com","areaname","controllername");
                        
            routes.MapRoute(
                  name: "default",
                  template: "{controller=Home}/{action=Index}/{id?}",
                  defaults: new { area = "web" });
        });
Nach dem Login kopieren

Die Implementierungsmethode ist vielleicht nicht die beste, aber Es erfüllt bereits die Grundbedürfnisse. Wenn Sie eine bessere Methode haben, können Sie diese gerne diskutieren und austauschen.

 

 

 

Das obige ist der detaillierte Inhalt vonSo binden Sie den Domänennamen der zweiten Ebene an einen bestimmten Controller in asp.net core mvc. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage