In ASP.NET Core 2.2, middleware is configured in the Startup class:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.Use(async (context, next) =>
{
context.Response.ContentType = "text/html; charset=utf-8";
await context.Response.WriteAsync("<h3>Middleware1 start</h3>");
await next();
await context.Response.WriteAsync("<h3>Middleware1 end</h3>");
});
app.Use(async (context, next) =>
{
await context.Response.WriteAsync("<h3>Middleware2 start</h3>");
await next();
await context.Response.WriteAsync("<h3>Middleware2 end</h3>");
});
app.Run(async context =>
await context.Response.WriteAsync("Pipeline complete"));
}
Understanding Middleware Architecture
The core middleware mechanism works through delegate composition:
public class MiddlewarePipeline
{
private readonly List<Func<RequestDelegate, RequestDelegate>> _components =
new List<Func<RequestDelegate, RequestDelegate>>();
public void Use(Func<RequestDelegate, RequestDelegate> middleware)
{
_components.Add(middleware);
}
public RequestDelegate Build()
{
RequestDelegate pipeline = context =>
{
context.Response.StatusCode = 404;
return Task.CompletedTask;
};
foreach (var component in _components.Reverse())
{
pipeline = component(pipeline);
}
return pipeline;
}
}
Custom Middleware Implementation Example
Here's a simplified middleware implementation:
public class CustomMiddleware
{
private List<Func<MiddlewareDelegate, MiddlewareDelegate>> _middleware =
new List<Func<MiddlewareDelegate, MiddlewareDelegate>>();
public void Add(Func<MiddlewareDelegate, MiddlewareDelegate> middleware)
{
_middleware.Add(middleware);
}
public MiddlewareDelegate BuildPipeline()
{
MiddlewareDelegate pipeline = msg => Task.CompletedTask;
foreach (var component in _middleware.Reverse())
{
pipeline = component(pipeline);
}
return pipeline;
}
}
public delegate Task MiddlewareDelegate(string message);
This demonstrates the fundamental pattern of ASP.NET Core middleware execution.