# Middleware in ASP.NET Core

The middleware are C# classes or functions that handle HTTP requests and responses. They are chained together, forming a pipeline, similarly to how HTTPHandlers can be chained in an HTTPClient.

All the requests pass through the middleware, so it's the right place to handle common cross-cutting concerns. The middleware can process the request/response, optionally modify it and pass on in the pipeline.

Requests/responses travel through the pipeline as HttpContext objects that can be modified.

Middleware components should be small and handle just one responsibility.

Middleware can short-circuit the request causing it not to be passed to the middleware parts behind it. If some middleware receives a request, it will also receive a response going back.

404

ASP.NET Core adds a middleware returning 404 in the end of the pipeline. If none of our middleware handles the requests, that 404 one handles it.

Middleware is added to the WebApplication (.NET 6) or to the IApplicationBuilder (prior to .NET 6).

In general, middleware is added like this:

app.UseMiddleware<WelcomePageMiddleware>();

Often, middleware comess with extension methods that are more readable:

app.UseWelcomePage(); // calls the above behind the scenes

Use

Methods starting with Use are a convention for adding middleware.

# Errors

The error handling should be added to the pipeline as early as possible to handle all errors. Useful middleware:

  • DeveloperExceptionPageMiddleware - displays stacktrace of an exception
  • ExceptionHandlerMiddleware - alternative to the above, more suitable for production
  • StatusCodePagesMiddleware - transforms raw error codes into some meaningful error-pages, it can redirect to different pages for different errors. It executes only if response payload is empty, making it possible to use it together with the ExceptionHandlerMiddleware.

Error Loop

In case of an exception, the ExceptionHandlerMiddleware reexecutes the middleware pipeline by redirecting to /Error (redirecting internally, not with 30X). If during that redirection another exeption is thrown, a raw error will be returned to the user.

# EndpointMiddleware

The actual content is generated by various EndpointMiddleware.

# Branching

Normally, middleware pipeline is a single line of components that execute one after another. We can change that and create branches where some requests go one way, while others go another way. We use Map for that.

app.UseDeveloperExceptionPage(); // always runs

app.Map("/branch", builder => 
{
    builder.UseExceptionHandler(); // executed only for paths starting with /branch
});

// always execute
app.UseStaticFiles();
app.UseRouting();
app.MapRazorPages();

# Middleware Endpoints

We can create simple endpoints in middleware with the Run extension method:

app.Run(async context => 
{
    context.Response.ContentType = "text/plain";
    await context.Response.WriteAsync("some content");
});
Last Updated: 10/5/2022, 6:26:29 PM