前書き
この記事は、私たちが独自のプロジェクトを開発する際に実際に使用しているものであり、単純な Hello World ではなく、より詳細なミドルウェアの使用法として考えることができます。
ミドルウェアの役割
どの Web フレームワークでも http リクエストがパイプラインにカプセル化され、各リクエストがパイプライン内の一連の操作を経て、最終的に作成したコードに到達することがわかっています。ミドルウェアは、リクエスト プロセスをインターセプトし、他の処理と応答を実行するために使用されるアプリケーション パイプライン内のコンポーネントです。多くのミドルウェアが存在する可能性があり、各ミドルウェアはパイプライン内のリクエストをインターセプトし、リクエストを次のミドルウェアに転送するかどうかを決定できます。
asp.net コアは、ミドルウェアを asp.net パイプライン要求に登録するための IApplicationBuilder インターフェイスを提供します。ミドルウェアは典型的な AOP アプリケーションです。
すべてのミドルウェアはリクエストの前後で動作できます。リクエストの処理が完了すると、次のリクエストに渡されます。
ミドルウェアの実行方法
デフォルトでは、ミドルウェアの実行順序は、Startup.cs ファイルの public void Configure(IApplicationBuilder app){} メソッドに登録された順序に基づきます。
パイプラインに「ミドルウェア」を登録する方法は3つほどあります
1.app.Use()、IApplicationBuilderインターフェースがネイティブで提供されており、登録等に使用します。
2.app.Run() は拡張メソッドです。これには Http コンテキスト情報が含まれる RequestDelegate デリゲートが必要です。これは常にパイプラインの最後のステップで実行されるため、次のパラメーターはありません。
3.app.Map() も MVC ルーティングと同様の拡張メソッドであり、通常、いくつかの特別なリクエスト パスを処理するために使用されます。例: www.example.com/token など。
上記の Run と Map は、IApplicationBuilder インターフェイスの拡張である Use を内部的に呼び出します。名前が十分に正確ではないと思われる場合は、次の拡張メソッドが本物の登録ミドルウェアであり、最も強力なメソッドでもあります。 。
app.UseMiddlewarea8093152e673feb7aba1828c43532094()、はい、それだけです。 なぜ強いと言われるのでしょうか?なぜなら、ミドルウェアを登録する機能だけでなく、将来ほとんどの場面で使用されるであろう依存性注入(DI)の機能も提供するからです。
ミドルウェアとフィルターの違い
MVC フレームワークに精通している学生は、MVC がリクエストの前後に実行する必要があるコードを処理するために使用できる 5 つの主要なフィルターも提供していることを知っているはずです。それらは、AuthenticationFilter、AuthorizationFilter、ActionFilter、ExceptionFilter、および ResultFilter です。
説明によると、ミドルウェアとフィルターの機能は似ていることがわかりますが、両者の違いは何でしょうか?なぜ別のミドルウェアを構築するのでしょうか?
実際、フィルターとミドルウェアは異なる焦点を持っており、異なる責任を持ち、異なることを実行することを意味します。
たとえば、ミドルウェアはアジノスの戦刃のようなもので、フィルターはドラゴンの怒り、タレッゴサの魂の杖のようなもので、戦士であるあなたはドラゴンの怒り、タレッゴサの魂を運ぶ杖を使って戦場で人々を殺すとします。 , ダメージは発生しますが、杖を持っているとダメージが低いだけでなく属性も低下します。
2 つの AOP ツールとして、フィルターはアプリケーション自体に焦点を当てており、Action と ActionResult を直接操作します。では、出力結果をフォーマットしたり、要求された ViewModel でデータ検証を実行したりする必要があります。Filter を使用する必要があります。これは MVC の一部であり、アクション コンテキストに関する一部の情報を傍受できますが、ミドルウェアにはこの機能がありません。
いつミドルウェアが必要になるのでしょうか?
それでは、いつミドルウェアを使用すべきでしょうか?私の理解では、認証、セッションストレージ、ロギングなど、パイプラインで実行する必要がある、ビジネスとはほとんど関係のないいくつかのことは、アプリケーションで使用できるということです。実際、asp.net core プロジェクト自体にはすでに多くのミドルウェアが含まれています。
たとえば、新しい asp.net core アプリケーションを作成するとき、デフォルトで生成されるテンプレート
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?}"); }); }
ソース コードをダウンロードするのが面倒なので、Reflector を使用してソース コードを表示します。
//扩展方法`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>()); } }
app.UseDeveloperExceptionPage()、app.UseStaticFiles() などがすべてミドルウェアを通じて実装されていることがわかります。
独自のミドルウェアをカスタマイズする方法
背景: プロジェクトでミドルウェアが使用されるシナリオでは、ユーザー (ユーザー) 情報を他の部門と共有する必要があります。 プラットフォームとサブシステムを例に挙げると、ユーザー情報、ログイン、登録などの機能をプラットフォーム上に配置するサブシステムを開発しています。これは、プラットフォームが Java 言語で開発されています。サブシステムにアクセスするには、ログインしているかどうかを確認する必要があるページもあれば、ログインしているかどうかを確認する必要がないページもあるため、Identity 機能を置き換える ID 検証システムが必要です。
幸运的是微软已经给我们提供了一套身份验证的中间件,在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。
我们需要一个流程图来理清逻辑思路,以便于写代码的时候思路更加的清晰。
平台有一个要求就是,用户在我们子系统退出之后,要调用平台的一个接口通知他们,他们要做一些后续的业务。
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中文网!