Heim  >  Artikel  >  Backend-Entwicklung  >  Tutorial zum Binden eines Domänennamens der zweiten Ebene an eine bestimmte Controller-Instanz

Tutorial zum Binden eines Domänennamens der zweiten Ebene an eine bestimmte Controller-Instanz

零下一度
零下一度Original
2017-06-17 10:24:081472Durchsuche

In diesem Artikel wird hauptsächlich beschrieben, wie der Second-Level-Domain-Name an einen bestimmten Controller in Asp.net Core MVC gebunden wird. Freunde, die ihn benötigen, können darauf verweisen

Anwendungsszenarien: Unternehmensportale richten unterschiedliche Abschnitte entsprechend unterschiedlichen Inhalten ein, z. B. verfügt Sina ü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 erfolgt 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"});
});

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);
   }
 }

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 einige Arbeit leisten und den Code direkt eingeben:


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;
    }
}

Abschließend können wir die entsprechenden Regeln im Startup registrieren, wie folgt:


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;
    }
}

Das obige ist der detaillierte Inhalt vonTutorial zum Binden eines Domänennamens der zweiten Ebene an eine bestimmte Controller-Instanz. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
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