Psaní vlastního middlewaru ASP.NET Core
Poznámka:
Toto není nejnovější verze tohoto článku. Aktuální verzi najdete v tomto článku ve verzi .NET 9.
Upozorňující
Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v tématu .NET a .NET Core Zásady podpory. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.
Důležité
Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Aktuální verzi najdete v tomto článku ve verzi .NET 9.
Fiyaz Hasan, 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.
Toto téma popisuje, jak psát middleware založený na konvencích. Přístup, který používá silné psaní a aktivaci na vyžádání, najdete v tématu Aktivace middlewaru založeného na továrně v ASP.NET Core.
Middleware – třída
Middleware je obecně zapouzdřen ve třídě a vystaven pomocí rozšiřující metody. Zvažte následující vložený middleware, který nastaví jazykovou verzi aktuálního požadavku z řetězce dotazu:
using System.Globalization;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseHttpsRedirection();
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(context);
});
app.Run(async (context) =>
{
await context.Response.WriteAsync(
$"CurrentCulture.DisplayName: {CultureInfo.CurrentCulture.DisplayName}");
});
app.Run();
Předchozí zvýrazněný vložený middleware se používá k předvedení vytvoření middlewarové komponenty voláním Microsoft.AspNetCore.Builder.UseExtensions.Use. Předchozí Use
metoda rozšíření přidá do kanálu požadavku aplikace delegovaný middleware definovaný v řádku.
Pro rozšíření jsou k dispozici Use
dvě přetížení:
- Jeden vezme HttpContext a
Func<Task>
.Func<Task>
Vyvolání bez jakýchkoli parametrů - Druhý si vezme
HttpContext
a RequestDelegate.RequestDelegate
Vyvoláním voláním metodyHttpContext
.
Preferujte použití pozdějšího přetížení, protože ukládá dvě interní přidělení požadavků, které jsou vyžadovány při použití jiného přetížení.
Otestujte middleware předáním jazykové verze. Například požadavek https://localhost:5001/?culture=es-es
.
Informace o integrované podpoře lokalizací ASP.NET Core najdete v tématu Globalizace a lokalizace v ASP.NET Core.
Následující kód přesune delegáta middlewaru do třídy:
using System.Globalization;
namespace Middleware.Example;
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);
}
}
Middleware třída musí obsahovat:
- Veřejný konstruktor s parametrem typu RequestDelegate.
- Veřejná metoda s názvem
Invoke
neboInvokeAsync
. Tato metoda musí:- Vrácení znaku
Task
. - Přijmout první parametr typu HttpContext.
- Vrácení znaku
Další parametry konstruktoru a Invoke
/InvokeAsync
jsou naplněny injektáží závislostí (DI).
Obvykle se vytvoří rozšiřující metoda pro zveřejnění middlewaru prostřednictvím IApplicationBuilder:
using System.Globalization;
namespace Middleware.Example;
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);
}
}
public static class RequestCultureMiddlewareExtensions
{
public static IApplicationBuilder UseRequestCulture(
this IApplicationBuilder builder)
{
return builder.UseMiddleware<RequestCultureMiddleware>();
}
}
Následující kód volá middleware z Program.cs
:
using Middleware.Example;
using System.Globalization;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseHttpsRedirection();
app.UseRequestCulture();
app.Run(async (context) =>
{
await context.Response.WriteAsync(
$"CurrentCulture.DisplayName: {CultureInfo.CurrentCulture.DisplayName}");
});
app.Run();
Závislosti middlewaru
Middleware by měl postupovat podle explicitního principu závislostí tím, že v jeho konstruktoru zpřístupňuje jeho závislosti. Middleware se konstruuje jednou za dobu životnosti aplikace.
Komponenty middlewaru mohou vyřešit své závislosti z injektáže závislostí (DI) prostřednictvím parametrů konstruktoru. UseMiddleware může také přijímat další parametry přímo.
Závislosti middlewaru pro jednotlivé požadavky
Middleware se konstruuje při spuštění aplikace, a proto má životnost aplikace. Služby s vymezenou životností používané konstruktory middlewaru se během každého požadavku nesdílí s jinými typy vloženými do závislostí. Pokud chcete sdílet vymezenou službu mezi middlewarem a jinými typy, přidejte tyto služby do InvokeAsync
podpisu metody. Metoda InvokeAsync
může přijmout další parametry, které jsou naplněny DI:
namespace Middleware.Example;
public class MyCustomMiddleware
{
private readonly RequestDelegate _next;
public MyCustomMiddleware(RequestDelegate next)
{
_next = next;
}
// IMessageWriter is injected into InvokeAsync
public async Task InvokeAsync(HttpContext httpContext, IMessageWriter svc)
{
svc.Write(DateTime.Now.Ticks.ToString());
await _next(httpContext);
}
}
public static class MyCustomMiddlewareExtensions
{
public static IApplicationBuilder UseMyCustomMiddleware(
this IApplicationBuilder builder)
{
return builder.UseMiddleware<MyCustomMiddleware>();
}
}
Možnosti životnosti a registrace obsahují kompletní ukázku middlewaru s vymezenými službami životnosti.
Následující kód slouží k otestování předchozího middlewaru:
using Middleware.Example;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddScoped<IMessageWriter, LoggingMessageWriter>();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseMyCustomMiddleware();
app.MapGet("/", () => "Hello World!");
app.Run();
Rozhraní IMessageWriter
a implementace:
namespace Middleware.Example;
public interface IMessageWriter
{
void Write(string message);
}
public class LoggingMessageWriter : IMessageWriter
{
private readonly ILogger<LoggingMessageWriter> _logger;
public LoggingMessageWriter(ILogger<LoggingMessageWriter> logger) =>
_logger = logger;
public void Write(string message) =>
_logger.LogInformation(message);
}
Další materiály
- Ukázkový kód použitý v tomto článku
- Zdroj UseExtensions na GitHubu
- Téma Možnosti registrace a doba života obsahuje kompletní ukázku middlewaru se službami scoped, transient a singleton.
- PODROBNÉ INFORMACE: JAK JE VYTVOŘENÝ KANÁL MIDDLEWARU ASP.NET CORE
- ASP.NET Core Middleware
- Testování middlewaru ASP.NET Core
- Migrace modulů a obslužných rutin HTTP do middlewaru ASP.NET Core
- Spuštění aplikace v ASP.NET Core
- Funkce požadavků v ASP.NET Core
- Aktivace middlewaru na základě objektu pro vytváření v ASP.NET Core
- Aktivace middlewaru s využitím kontejneru třetí strany v ASP.NET Core
Autor: 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 konvencích. Přístup, který používá silné psaní a aktivaci na vyžádání, najdete v tématu Aktivace middlewaru založeného na továrně v ASP.NET Core.
Middleware – třída
Middleware je obecně zapouzdřen ve třídě a vystaven pomocí rozšiřující metody. Představte si následující middleware, který nastaví jazykovou verzi aktuálního požadavku 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 o integrované podpoře lokalizací ASP.NET Core najdete v tématu Globalizace a lokalizace v ASP.NET Core.
Otestujte middleware předáním jazykové verze. Například požadavek https://localhost:5001/?culture=no
.
Následující kód přesune delegáta middlewaru 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);
}
}
}
Middleware třída musí obsahovat:
- Veřejný konstruktor s parametrem typu RequestDelegate.
- Veřejná metoda s názvem
Invoke
neboInvokeAsync
. Tato metoda musí:- Vrácení znaku
Task
. - Přijmout první parametr typu HttpContext.
- Vrácení znaku
Další parametry konstruktoru a Invoke
/InvokeAsync
jsou naplněny injektáží závislostí (DI).
Závislosti middlewaru
Middleware by měl postupovat podle explicitního principu závislostí tím, že v jeho konstruktoru zpřístupňuje jeho závislosti. Middleware se konstruuje jednou za dobu životnosti aplikace. Pokud potřebujete sdílet služby s middlewarem v rámci požadavku, přečtěte si část Závislostí middlewaru podle požadavku.
Komponenty middlewaru mohou vyřešit své závislosti z injektáže závislostí (DI) prostřednictvím parametrů konstruktoru. UseMiddleware může také přijímat další parametry přímo.
Závislosti middlewaru pro jednotlivé požadavky
Vzhledem k tomu, že middleware se vytváří při spuštění aplikace, nikoli při každém požadavku, nejsou během každého požadavku sdíleny s jinými typy vloženými do závislostí. Pokud musíte sdílet vymezenou službu mezi middlewarem a dalšími typy, přidejte tyto služby do InvokeAsync
podpisu metody. Metoda InvokeAsync
může přijmout další parametry, které jsou naplněny DI:
public class CustomMiddleware
{
private readonly RequestDelegate _next;
public CustomMiddleware(RequestDelegate next)
{
_next = next;
}
// IMyScopedService is injected into InvokeAsync
public async Task InvokeAsync(HttpContext httpContext, IMyScopedService svc)
{
svc.MyProperty = 1000;
await _next(httpContext);
}
}
Možnosti životnosti a registrace obsahují kompletní ukázku middlewaru s vymezenými službami životnosti.
Metoda rozšíření middlewaru
Následující metoda rozšíření zpřístupň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ší materiály
- Téma Možnosti registrace a doba života obsahuje kompletní ukázku middlewaru se službami scoped, transient a singleton.
- ASP.NET Core Middleware
- Testování middlewaru ASP.NET Core
- Migrace modulů a obslužných rutin HTTP do middlewaru ASP.NET Core
- Spuštění aplikace v ASP.NET Core
- Funkce požadavků v ASP.NET Core
- Aktivace middlewaru na základě objektu pro vytváření v ASP.NET Core
- Aktivace middlewaru s využitím kontejneru třetí strany v ASP.NET Core