Psaní vlastních ASP.NET Core middlewaru

Rick Anderson a Steve Smith

Middleware je software sestavený do kanálu aplikace pro zpracování požadavků a odpovědí. ASP.NET Core poskytuje bohatou sadu integrovaných komponent middlewaru, ale v některých scénářích můžete chtít napsat vlastní middleware.

Poznámka

Toto téma popisuje, jak psát middleware založený na konvenci. Přístup, který používá silné psaní a aktivaci na žádost, najdete v tématu Aktivace middlewaru založená na továrně v ASP.NET Core .

Middleware – třída

Middleware je obecně zapouzdřen ve třídě a zpřístupněn pomocí metody rozšíření. Vezměte v úvahu následující middleware, který nastaví jazykovou verzi pro aktuální požadavek z řetězce dotazu:

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

    }
}

Předchozí vzorový kód slouží k předvedení vytvoření komponenty middlewaru. Informace ASP.NET Core integrovanou podporu lokalizace najdete v tématu Globalizace a lokalizace v ASP.NET Core .

Otestujte middleware předáním jazykové verze. Například si vyžádejte https://localhost:5001/?culture=no .

Následující kód přesune middlewarový delegát do třídy :

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

Třída middlewaru musí obsahovat:

  • Veřejný konstruktor s parametrem typu RequestDelegate .
  • Veřejná metoda s názvem Invoke nebo InvokeAsync . Tato metoda musí:
    • Vrátí Task .
    • Přijměte první parametr typu HttpContext .

Další parametry pro konstruktor a Invoke / InvokeAsync jsou naplněny injektáží závislostí (DI).

Závislosti middlewaru

Middleware by měl postupovat podle principu explicitních závislostí tak, že své závislosti vystaví ve svém konstruktoru. Middleware se konstruoval jednou pro každou životnost aplikace. Pokud potřebujete sdílet služby s middlewarem v rámci požadavku, podívejte se do části Závislosti middlewaru na žádost.

Komponenty middlewaru vyřešit své závislosti z injektáže závislostí (DI) prostřednictvím parametrů konstruktoru. UseMiddleware < T > může také přijímat další parametry přímo.

Závislosti middlewaru pro každý požadavek

Vzhledem k tomu, že middleware je vytvořený při spuštění aplikace, nikoli při zpracování jednotlivých požadavků, služby doby života používané konstruktory middlewaru se během každého požadavku nesměšují s jinými typy vloženého do závislostí. Pokud musíte sdílet vymezenou službu mezi middlewarem a jinými typy, přidejte tyto služby do Invoke podpisu metody. Metoda Invoke může přijímat další parametry, které jsou naplněné dinachem:

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

Možnosti doby života a registrace obsahují kompletní ukázku middlewaru se službami doby života s vymezenou životností.

Metoda rozšíření middlewaru

Následující rozšiřující metoda zveřejňuje middleware prostřednictvím IApplicationBuilder :

using Microsoft.AspNetCore.Builder;

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

Následující kód volá middleware z Startup.Configure :

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

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

Další zdroje informací