AspNetCore.Docs/aspnetcore/fundamentals/middleware/write.md

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:

[!code-csharp]

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:

[!code-csharp]

The middleware class must include:

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:

[!code-csharp]

The following code calls the middleware from Startup.Configure:

[!code-csharp]

Additional resources