撰寫自訂的 ASP.NET Core 中介軟體

Rick AndersonSteve Smith 撰寫

中介軟體為組成應用程式管線的軟體,用以處理要求與回應。 ASP.NET Core 提供一組豐富的內建中介軟體元件,但在某些情況下,您可能想要撰寫自訂的中介軟體。

注意

本主題說明如何撰寫以 慣例為基礎的 中介軟體。 如需使用強式輸入和依要求啟用的方法,請參閱 ASP.NET Core 的 Factory 中介軟體啟用

中介軟體類別

中介軟體通常封裝在類別中,並以擴充方法公開。 請考慮下列中介軟體,其會為來自查詢字串的目前要求設定文化特性:

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.Use(async (context, next) =>
        {
            var cultureQuery = context.Request.Query["culture"];
            if (!string.IsNullOrWhiteSpace(cultureQuery))
            {
                var culture = new CultureInfo(cultureQuery);

                CultureInfo.CurrentCulture = culture;
                CultureInfo.CurrentUICulture = culture;
            }

            // Call the next delegate/middleware in the pipeline
            await next();
        });

        app.Run(async (context) =>
        {
            await context.Response.WriteAsync(
                $"Hello {CultureInfo.CurrentCulture.DisplayName}");
        });

    }
}

上述範例程式碼用於示範中介軟體元件的建立。 如需 ASP.NET Core 的內建當地語系化支援,請參閱 ASP.NET Core 全球化和當地語系化

藉由傳入文化特性來測試中介軟體。 例如,要求 https://localhost:5001/?culture=no

下列程式碼會將中介軟體委派移至類別:

using Microsoft.AspNetCore.Http;
using System.Globalization;
using System.Threading.Tasks;

namespace Culture
{
    public class RequestCultureMiddleware
    {
        private readonly RequestDelegate _next;

        public RequestCultureMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task InvokeAsync(HttpContext context)
        {
            var cultureQuery = context.Request.Query["culture"];
            if (!string.IsNullOrWhiteSpace(cultureQuery))
            {
                var culture = new CultureInfo(cultureQuery);

                CultureInfo.CurrentCulture = culture;
                CultureInfo.CurrentUICulture = culture;

            }

            // Call the next delegate/middleware in the pipeline
            await _next(context);
        }
    }
}

中介軟體類別必須包含:

  • 具有 RequestDelegate 類型參數的公用建構函式。
  • 名為 InvokeInvokeAsync 的公用方法。 此方法必須:
    • 傳回 Task
    • 接受 HttpContext 類型的第一個參數。

建構函式和 Invoke/InvokeAsync 的其他參數會由相依性插入 (DI) 所填入。

中介軟體相依性

中介軟體應於其建構函式中公開其相依性,以遵循明確的相依性原則。 中介軟體會在每次「應用程式存留期」就建構一次。 若您需要在要求內與中介軟體共用服務,請參閱依要求的中介軟體相依性一節。

中介軟體元件可透過建構函式參數,解析其來自相依性插入 (DI) 的相依性。 UseMiddleware<T> 也可直接接受其它參數。

依要求的中介軟體相依性

因為中介軟體建構於應用程式啟動時,而非依要求建構,所以在每個要求期間,中介軟體建構函式使用的「已限定範圍」存留期服務不會與其它插入相依性的類型共用。 如果您必須在中介軟體和其他類型間共用「已限定範圍」的服務,請將這些服務新增至 Invoke 方法的簽章。 Invoke 方法可以接受 DI 所填入的其他參數:

public class CustomMiddleware
{
    private readonly RequestDelegate _next;

    public CustomMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    // IMyScopedService is injected into Invoke
    public async Task Invoke(HttpContext httpContext, IMyScopedService svc)
    {
        svc.MyProperty = 1000;
        await _next(httpContext);
    }
}

存留期和註冊選項 包含具有 範圍 存留期服務之中介軟體的完整範例。

中介軟體擴充方法

下列擴充方法透過 IApplicationBuilder 公開中介軟體:

using Microsoft.AspNetCore.Builder;

namespace Culture
{
    public static class RequestCultureMiddlewareExtensions
    {
        public static IApplicationBuilder UseRequestCulture(
            this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<RequestCultureMiddleware>();
        }
    }
}

下列程式碼會從 Startup.Configure 呼叫中介軟體:

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.UseRequestCulture();

        app.Run(async (context) =>
        {
            await context.Response.WriteAsync(
                $"Hello {CultureInfo.CurrentCulture.DisplayName}");
        });
    }
}

其他資源