4.0 KiB
title | author | description | monikerRange | ms.author | ms.custom | ms.date | uid |
---|---|---|---|---|---|---|---|
Write custom ASP.NET Core middleware | rick-anderson | Learn how to write custom ASP.NET Core middleware. | >= aspnetcore-2.1 | riande | mvc | 08/22/2019 | fundamentals/middleware/write |
Write custom ASP.NET Core middleware
By Rick Anderson and Steve Smith
Middleware is software that's assembled into an app pipeline to handle requests and responses. ASP.NET Core provides a rich set of built-in middleware components, but in some scenarios you might want to write a custom middleware.
Middleware class
Middleware is generally encapsulated in a class and exposed with an extension method. Consider the following middleware, which sets the culture for the current request from a query string:
The preceding sample code is used to demonstrate creating a middleware component. For ASP.NET Core's built-in localization support, see xref:fundamentals/localization.
Test the middleware by passing in the culture. For example, request https://localhost:5001/?culture=no
.
The following code moves the middleware delegate to a class:
The middleware class must include:
- A public constructor with a parameter of type xref:Microsoft.AspNetCore.Http.RequestDelegate.
- A public method named
Invoke
orInvokeAsync
. This method must:- Return a
Task
. - Accept a first parameter of type xref:Microsoft.AspNetCore.Http.HttpContext.
- Return a
Additional parameters for the constructor and Invoke
/InvokeAsync
are populated by dependency injection (DI).
Middleware dependencies
Middleware should follow the Explicit Dependencies Principle by exposing its dependencies in its constructor. Middleware is constructed once per application lifetime. See the Per-request middleware dependencies section if you need to share services with middleware within a request.
Middleware components can resolve their dependencies from dependency injection (DI) through constructor parameters. UseMiddleware<T> can also accept additional parameters directly.
Per-request middleware dependencies
Because middleware is constructed at app startup, not per-request, scoped lifetime services used by middleware constructors aren't shared with other dependency-injected types during each request. If you must share a scoped service between your middleware and other types, add these services to the Invoke
method's signature. The Invoke
method can accept additional parameters that are populated by 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);
}
}
Middleware extension method
The following extension method exposes the middleware through xref:Microsoft.AspNetCore.Builder.IApplicationBuilder:
The following code calls the middleware from Startup.Configure
: