1. 程式人生 > >在ASP.NET Core中編寫合格的中介軟體

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

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