Heim  >  Artikel  >  Backend-Entwicklung  >  Eine kurze Diskussion über die ASP.NET Core-Middleware, ausführliche Erklärung und Projektpraxis

Eine kurze Diskussion über die ASP.NET Core-Middleware, ausführliche Erklärung und Projektpraxis

高洛峰
高洛峰Original
2016-12-26 10:17:021718Durchsuche

Vorwort

Dieser Artikel wird tatsächlich von uns bei der Entwicklung unserer eigenen Projekte verwendet. Er eignet sich eher für praktische Anwendungen. Er kann als eine vertiefte Verwendung von Middleware angesehen werden, nicht als einfache Hallo-Welt.

Die Rolle der Middleware

Wir wissen, dass jedes Web-Framework HTTP-Anfragen in einer Pipeline kapselt und jede Anfrage durch die Pipeline gelangt. Schließlich gelangt eine Reihe von Vorgängen zu dem Code, den wir erhalten schrieb. Dann ist Middleware eine Komponente in der Anwendungspipeline, die verwendet wird, um den Anforderungsprozess abzufangen und eine andere Verarbeitung und Antwort durchzuführen. Es kann viele Middlewares geben, und jede Middleware kann Anforderungen in der Pipeline abfangen und entscheiden, ob die Anforderung an die nächste Middleware weitergeleitet wird.

asp.net Core bietet die IApplicationBuilder-Schnittstelle zum Registrieren von Middleware in asp.net-Pipeline-Anfragen. Middleware ist eine typische AOP-Anwendung.
Jede Middleware kann vor und nach der Anfrage arbeiten. Nachdem die Anforderungsverarbeitung abgeschlossen ist, wird sie an die nächste Anforderung übergeben.

Wie Middleware ausgeführt wird

Standardmäßig basiert die Ausführungsreihenfolge der Middleware auf der Reihenfolge, die in der öffentlichen void-Methode „Configure(IApplicationBuilder app){}“ in der Datei „Startup.cs“ registriert ist.

Es gibt etwa drei Möglichkeiten, „Middleware“ in der Pipeline zu registrieren

1.app.Use(), die IApplicationBuilder-Schnittstelle wird nativ bereitgestellt und verwendet zur Anmeldung etc. .

2.app.Run() ist eine Erweiterungsmethode. Sie erfordert einen RequestDelegate-Delegaten, der HTTP-Kontextinformationen enthält, da er immer im letzten Schritt der Pipeline ausgeführt wird .

3.app.Map() ist ebenfalls eine Erweiterungsmethode, ähnlich dem MVC-Routing. Sie wird im Allgemeinen zur Verarbeitung einiger spezieller Anforderungspfade verwendet. Zum Beispiel: www.example.com/token usw.

Das oben genannte „Run and Map“ ruft auch intern „Use“ auf, eine Erweiterung der IApplicationBuilder-Schnittstelle. Wenn Sie der Meinung sind, dass der Name nicht genau genug ist, dann ist die folgende Erweiterungsmethode die authentische Registrierungs-Middleware und auch die beste mächtig.

app.UseMiddlewarea8093152e673feb7aba1828c43532094(), ja, das ist es. Warum soll es mächtig sein? Denn es bietet nicht nur die Funktion der Registrierung von Middleware, sondern auch die Funktion der Abhängigkeitsinjektion (DI), die in Zukunft in den meisten Situationen verwendet wird.

Der Unterschied zwischen Middleware und Filter

Studenten, die mit dem MVC-Framework vertraut sind, sollten wissen, dass MVC auch 5 Hauptfilter bereitstellt, die wir zur Verarbeitung von Anfragen verwenden können und die vorher und nachher ausgeführt werden müssen Code. Dies sind AuthenticationFilter, AuthorizationFilter, ActionFilter, ExceptionFilter und ResultFilter.

Der Beschreibung zufolge sind die Funktionen von Middleware und Filtern ähnlich. Was ist also der Unterschied zwischen ihnen? Warum eine weitere Middleware bauen?
Tatsächlich haben Filter und Middleware unterschiedliche Schwerpunkte, was bedeutet, dass sie unterschiedliche Verantwortlichkeiten haben und unterschiedliche Aufgaben erledigen.

Zum Beispiel ist die Middleware wie die Warblade von Azzinoth, der Filter ist wie Dragon's Wrath, Tarecgosas Seelenstab, du bist ein Krieger, der Dragon's Wrath hält, Tai Legosas seelentragender Stab geht ins Spiel, um Menschen zu töten Obwohl es Schaden verursacht, ist der Schaden, den Sie mit dem Stab anrichten, nicht nur gering, sondern verringert auch die Attribute.

Als zwei AOP-Tools ist der Filter besser für das Unternehmen geeignet. Er konzentriert sich auf die Anwendung selbst. Wenn Sie sich beispielsweise ActionFilter und ResultFilter ansehen, interagieren sie direkt mit Ihrem Action und ActionResult Von Ihnen? Es fühlt sich sehr nah an. Dann muss ich noch einige Dinge tun, zum Beispiel meine Ausgabeergebnisse formatieren und die Daten meines angeforderten ViewModels überprüfen. Es ist Teil von MVC. Es kann einige Informationen über Ihren Aktionskontext abfangen, aber Middleware verfügt nicht über diese Fähigkeit.

Wann brauchen wir Middleware?

Wann sollten wir also Middleware verwenden? Ich verstehe, dass einige Dinge, die in der Pipeline erledigt werden müssen und wenig mit dem Geschäft zu tun haben, in unseren Anwendungen verwendet werden können, wie z. B. Authentifizierung, Sitzungsspeicherung, Protokollierung usw. Tatsächlich enthält unser asp.net-Kernprojekt selbst bereits eine Menge Middleware.

Wenn wir beispielsweise eine neue asp.net-Kernanwendung erstellen, sind die standardmäßig generierten Vorlagen

public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
  app.UseDeveloperExceptionPage();
   
  app.UseStaticFiles();
   
  loggerFactory.AddConsole();
   
  app.UseMvc(routes =>
  {
    routes.MapRoute(
      name: "default",
      template: "{controller=Home}/{action=Index}/{id?}");
  });
}

zu faul Download Der Quellcode ist verfügbar. Wir verwenden Reflector, um den Quellcode anzuzeigen:

//扩展方法`app.UseDeveloperExceptionPage();`
public static class DeveloperExceptionPageExtensions
{
  // Methods
  public static IApplicationBuilder UseDeveloperExceptionPage(this IApplicationBuilder app)
  {
    if (app == null)
    {
      throw new ArgumentNullException("app");
    }
    return UseMiddlewareExtensions.UseMiddleware<DeveloperExceptionPageMiddleware>(app, Array.Empty<object>());
  }
}

//扩展方法`app.UseStaticFiles();`
public static class StaticFileExtensions
{
  // Methods
  public static IApplicationBuilder UseStaticFiles(this IApplicationBuilder app)
  {
    if (app == null)
    {
      throw new ArgumentNullException("app");
    }
    return UseMiddlewareExtensions.UseMiddleware<StaticFileMiddleware>(app, Array.Empty<object>());
  }
}

Sie können die App sehen .UseDeveloperExceptionPage(), app .UseStaticFiles() usw. werden alle über Middleware implementiert.

So passen Sie Ihre eigene Middleware an

Hintergrund: Das Szenario, in dem Middleware in unserem Projekt verwendet wird, besteht darin, dass wir Benutzerinformationen (Benutzerinformationen) mit anderen Abteilungen teilen müssen. Am Beispiel der Plattform und des Subsystems entwickeln wir ein Subsystem, in dem Benutzerinformationen, Anmeldung, Registrierung und andere Funktionen auf der Plattform platziert werden. Die Plattform wird in Java-Sprache entwickelt Auf einige Seiten muss überprüft werden, ob Sie angemeldet sind. Auf anderen Seiten muss nicht überprüft werden, ob Sie angemeldet sind. Daher ist ein Identitätsüberprüfungssystem erforderlich, um die Identitätsfunktion zu ersetzen.

幸运的是微软已经给我们提供了一套身份验证的中间件,在Microsoft.AspNetCore.Authentication命名空间下,我们只需要拓展,添加自己的功能就行了 。具体怎么做呢?直接看代码吧。

根据约定俗成,中间件类需要有一个Invoke方法,签名是public async Task Invoke(HttpContext context){},下面是一个中间件的示例类:

public class RequestLoggerMiddleware
{
  private readonly RequestDelegate _next;
  private readonly ILogger _logger;
 
  public RequestLoggerMiddleware(RequestDelegate next, ILoggerFactory loggerFactory)
  {
    _next = next;
    _logger = loggerFactory.CreateLogger<RequestLoggerMiddleware>();
  }
 
  public async Task Invoke(HttpContext context)
  {
    _logger.LogInformation("Handling request: " + context.Request.Path);
    await _next.Invoke(context);
    _logger.LogInformation("Finished handling request.");
  }
}

   

了解了上面的约定之后,我们就开始定义我们自己的中间件Class。

我们需要一个流程图来理清逻辑思路,以便于写代码的时候思路更加的清晰。

浅谈ASP.NET Core 中间件详解及项目实战

平台有一个要求就是,用户在我们子系统退出之后,要调用平台的一个接口通知他们,他们要做一些后续的业务。

OK,开始撸码。

首先创建一个PlatformAuthoricationMiddleware,它继承于Microsoft.AspNetCore.Authentication下的类AuthenticationMiddleware,由于AuthenticationMiddleware已经实现了Invoke功能,所以我们只需要重写(override)它里面的一些方法就可以了。等等,我们好像还需要一些配置,比如流程图中的ReturnUrl,平台的Cookie的Key值,平台验证用户合法性的接口地址等参数。

建立一个Options类进行配置的设置,我们取名字为:PlatformAuthenticationOptions,继承AuthenticationOptions,并且实现掉IOptions8742468051c85b06f0a0af9e3e506b5c接口,这样子就能在Startup中直接配置了。

我们只需要重写AuthenticationMiddleware中的CreateHandler方法就行了,在Handler中可以实现掉我们中间件的功能。

然后创建一个处理的Handler类,取名为PlatformAuthenticationHandler,继承于AuthenticationHandler58fec2039d3938dc329cad313e09b70a用来处理请求中的调用。

至此,我们的核心需要的类已经建立完了,剩下的就是填充代码。

1.在PlatformAuthenticationHandler中重写HandleAuthenticateAsync()方法 , 进行主流程的控制。

2.在PlatformAuthenticationHandler中重写FinishResponseAsync()方法,进行Session的存储操作。

3.在PlatformAuthenticationHandler中重写HandleSignOutAsync()方法,进行登出的控制,因为用户登出之后我们要通知平台做一些其他操作。

4.在PlatformAuthenticationHandler中重写HandleUnauthorizedAsync()方法,进行未认证操作。

最后,我们需要一个扩展类来把我们的中间件以扩展方法注册到管道当中去 。

public static class MiddlewareExtensions
{
  public static IApplicationBuilder UsePlatformAuthentication(this IApplicationBuilder app) {
    if (app == null) {
      throw new ArgumentNullException(nameof(app));
    }
 
    return app.UseMiddleware<PlatformAuthenticationMiddleware>();
  }
 
  public static IApplicationBuilder UsePlatformAuthentication(this IApplicationBuilder app, CookieAuthenticationOptions options) {
    if (app == null) {
      throw new ArgumentNullException(nameof(app));
    }
    if (options == null) {
      throw new ArgumentNullException(nameof(options));
    }
 
    return app.UseMiddleware<PlatformAuthenticationMiddleware>(Options.Create(options));
  }
}

   

在Startup中就是app.UsePlatformAuthentication()

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) {
  loggerFactory.AddConsole(Configuration.GetSection("Logging"));
 
  //注册PlatformAuthentication中间件
  app.UsePlatformAuthentication(new PlatformAuthenticationOptions() {
    UserSessionStore = new UserSessionStore(),
  });
 
  app.UseMvc();
}

   

现在,我们的中间件核心业务流程的实现已经出来了,我就不大篇幅的粘贴代码了,会影响阅读,感兴趣具体实现的朋友可以去下面的地址查看代码,有具体流程的注释。

以上就是本文的全部内容,希望对大家的学习有所帮助,更多浅谈ASP.NET Core 中间件详解及项目实战相关文章请关注PHP中文网!

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