在ASP.NET Core中編寫合格的中間件


  這篇文章探討了讓不同的請求去使用不同的中間件,那么我們應該如何配置ASP.NET Core中間件?其實中間件只是在ASP.NET Core中處理Web請求的管道。所有ASP.NET Core應用程序至少需要一個中間件來響應請求,並且您的應用程序實際上只是中間件的集合。當然MVC管道本身就是中間件,早在WebForm時代就出現過HttpModules、HttpHandler、那個時候悠然記得我通過它們來組織我的廣告系統,不閑扯我們繼續。

  每個中間件組件都有一個帶有HttpContext參數的Invoke方法。您可以使用這個參數來處理方法。

public async Task Invoke(HttpContext context)
{
    if (context.Request.Path...)
    {
        await context.Response.WriteAsync("writing text...");
    }
}

   應用程序中最頂層的中間件將始終針對每個請求被調用。這是由.NET框架自動完成的。中間件可以向客戶端發送響應,也可以調用下一個中間件。對於后一種選擇,它當然需要訪問下一個中間件組件。這就是為什么大多數中間件組件都是使用帶有RequestDelegate參數的構造函數定義的。總之,RequestDelegate會自動填充,您無需在意。

   中間件在Startup.cs的Configure方法中注冊。Configure方法具有IApplicationBuilder參數,該參數提供了所有類型的中間件注冊所需的方法,我們試着去編寫一個中間件。

public class MyCustomMiddleware
    {
        private readonly RequestDelegate _next;
        public MyCustomMiddleware(RequestDelegate next)
        {
            _next = next;
        }
        public async Task Invoke(HttpContext context, IWebHostEnvironment env)
        {
            context.Response.Headers["app-name"] = env.ApplicationName+"Zaranet";
            context.Response.Headers["env-name"] = env.EnvironmentName+ "Zaranet";
            await _next(context);
        }
    }

隨后我們在Startup.cs的Configure方法中通過 use 來注冊自定義中間件。

public void Configure(IApplicationBuilder app, ...)
{
    app.UseMyCustomMiddleware();
}

  啟動程序我們發現一些正常,我們得到了我們想要的效果。

 

  但實際上,您很少需要直接調用UseMiddleware,因為中間件作者的標准方法是編寫特定於所注冊中間件的擴展方法:

using MiddlerWareSolucation.MiddlerWare;
using Microsoft.AspNetCore.Builder;
namespace MiddlerWareSolucation.MiddlerWare_Extensions { public static class MyCustomMiddlewareExtensions { public static IApplicationBuilder UseMyCustomMiddleware(this IApplicationBuilder app) { app.UseMiddleware<MyCustomMiddleware>(); return app; } } }

隨后直接調用Extensions擴展方法,效果還是一樣的。

public void Configure(IApplicationBuilder app, ...)
{
    app.UseMyCustomMiddleware();
}

 部分時候我們想要通過客戶端請求的路徑來對我們的中間件進行啟動,當然 MapWhen 允許您通過指定謂詞將中間件管道分成兩個完全獨立的分支:

app.UseMiddlewareOne();

app.MapWhen(context => context.Request.Path.StartsWithSegments("/api"), appBuilder =>
{
     appBuilder.UseMiddlewareTwo();
});

app.UseMiddlewareThree();

在此示例中,中間件One將始終執行,如果請求路徑以“ / api”開頭,則將執行中間件Two。否則,將執行中間件Three。使用這種配置,中間件2和中間件3都無法針對單個請求執行。

我想說的是最后一種情況是,您希望大多數中間件針對所有請求運行,但是您有一些條件件-特定中間件僅應針對某些請求運行。

這可以通過UseWhen輕松實現,UseWhen還使用謂詞來確定中間件是否應該運行:

app.UseWhen(context => context.Request.Path.StartsWithSegments("/api"), appBuilder =>
{
    appBuilder.UseStatusCodePagesWithReExecute("/apierror/{0}");

    appBuilder.UseExceptionHandler("/apierror/500");
});

這樣就可以通過選擇注冊方式來自己控制中間件。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM