- Middleware is software that's assembled into an application pipeline to handle requests and responses.
- It chooses whether to pass the request to the next component in the pipeline.
- It can perform work before and after the next component in the pipeline is invoked.
- Request delegates are used to build the request pipeline.
- The request delegates handle each HTTP request.
- Request delegates are configured using
Run
, Map
, and Use
extension methods.
- An individual request delegate can be specified in-line as an anonymous method (called in-line middleware), or it can be defined in a reusable class.
- Each middleware component in the request pipeline is responsible for invoking the next component in the pipeline, or short-circuiting the chain if appropriate.
- Short-circuiting is often desirable because it avoids unnecessary work.
- For example, the static file middleware can return a request for a static file and short-circuit the rest of the pipeline.
- Exception-handling delegates need to be called early in the pipeline, so they can catch exceptions that occur in later stages of the pipeline.
public void Configure(IApplicationBuilder app)
{
app.Run(async context =>
{
await context.Response.WriteAsync("Hello, World!");
});
}
- The first
app.Run
delegate terminates the pipeline. You can chain multiple request delegates together with app.Use
.
- The
next
parameter represents the next delegate in the pipeline.
- Remember that you can short-circuit the pipeline by not calling the next parameter.
- You can typically perform actions both before and after the next delegate, as this example demonstrates:
public void Configure(IApplicationBuilder app)
{
app.Use(async (context, next) =>
{
// Do work that doesn't write to the Response.
await next.Invoke();
// Do logging or other work that doesn't write to the Response.
});
app.Run(async context =>
{
await context.Response.WriteAsync("Hello from 2nd delegate.");
});
}
- Don't call
next.Invoke
after the response has been sent to the client.
- Changes to
HttpResponse
after the response has started will throw an exception.
- For example, changes such as setting headers, status code, etc, will throw an exception.
- Writing to the response body after calling
next
:
- May cause a protocol violation.
- For example, writing more than the stated
content-length
.
- May corrupt the body format. For example, writing an HTML footer to a CSS file.
HttpResponse.HasStarted
is a useful hint to indicate if headers have been sent and/or the body has been written to.
Ordering
- The order that middleware components are added in the
Configure
method defines the order in which they're invoked on requests, and the reverse order for the response.
- Typically,
UseExceptionHandler
is the first middleware component added to the pipeline.
- therefore, it catches any exceptions that occur in later calls.
- The static file middleware is called early in the pipeline so it can handle requests and short-circuit without going through the remaining components.
- The static file middleware provides no authorization checks.
- Any files served by it, including those under wwwroot, are publicly available.