Psaní vlastního middlewaru ASP.NET Core
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ší prostředky
- 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ší prostředky
- 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
Váš názor
https://aka.ms/ContentUserFeedback.
Připravujeme: V průběhu roku 2024 budeme postupně vyřazovat problémy z GitHub coby mechanismus zpětné vazby pro obsah a nahrazovat ho novým systémem zpětné vazby. Další informace naleznete v tématu:Odeslat a zobrazit názory pro