In ASP.NET Core, middleware is the term used for components
that form the Request Pipeline.
The pipeline request is like a chain, which can contain
multiple middlewares. These components will handle the request in sequence;
each component will inspect the request and decide whether it should be passed
to the next middleware or just generate a response interrupting the chain.
Once the request has been handled a response will be
generated and send back to the client passing along the chain.
Execution Order
Middlewares will execute in the same order they are
registered when handling requests and in the reverse order when handling
responses.
How to create a Middleware
Middleware components don`t implement interfaces or derive
from classes, It simply has a constructor that takes RequestDelegate as
parameter and implements the Invoke Method.
The RequestDelegate represents the next Middleware component
of the chain and the Invoke method is called when the component receives a
request.
Next I will show a few examples.
Creating Content-Generating Middleware
The most important type of middleware generates content for
clients, and it is this category to which MVC belongs.
This kind of middleware is used when you want to generate
some content and send it back to the client without the need of dealing with
all the MVC complexity.
Check the implementation below:
public class ContentMiddleware
{
private RequestDelegate nextDelegate;
public ContentMiddleware(RequestDelegate next) => nextDelegate = next;
public async Task
Invoke(HttpContext httpContext)
{
if (httpContext.Request.Path.ToString().ToLower() == "/content-middleware")
{
await httpContext.Response.WriteAsync(
"This
content was generated by the middleware",
Encoding.UTF8);
}
else
{
await nextDelegate.Invoke(httpContext);
}
}
}
Creating Short-Circuiting Middleware
Short-Circuiting Middleware Components are used when you
want to inspect the request and decide if the request should be passed to next component
or not.
The example below is checking if it the request contains the
User-Id header, if not the middleware will break the chain and return a
401-Unauthorized response to the client.
public class ShortCircuitMiddleware
{
private RequestDelegate nextDelegate;
public ShortCircuitMiddleware(RequestDelegate next) => nextDelegate = next;
public async Task
Invoke(HttpContext httpContext)
{
if (!httpContext.Request.Headers["User-Id"].Any())
{
httpContext.Response.StatusCode
= (int)HttpStatusCode.Unauthorized;
}
else
{
await nextDelegate.Invoke(httpContext);
}
}
}
Creating Request-Editing Middleware
The next type of middleware component examined doesn’t
generate a response. Instead, it changes requests before they reach other
components later in the chain. This kind of middleware is mainly used for
platform integration to enrich the ASP.NET Core representation of an HTTP
request with platform-specific features.
The example below will check if the request contains a blank
User-Id in the header and if yes it will be removed.
public async Task Invoke(HttpContext
httpContext)
{
if (httpContext.Request.Headers["User-Id"].Any() &&
string.IsNullOrWhiteSpace(httpContext.Request.Headers["User-Id"].ToString()))
{
httpContext.Request.Headers.Remove("User-Id");
}
else
{
await nextDelegate.Invoke(httpContext);
}
}
Interacting with another Middleware
Middleware components can interact with each other, let`s
consider that RequestEditMiddleware is executed before the
ShortCircuitMiddleware.
In that case if a request contains blank User-Id Header the RequestEditMiddleware
will remove that header from the request and call the next component, which is
the ShortCircuitMiddleware, the ShortCircuitMiddleware won`t find the header
User-Id and will break the chain returning a 401 response to the client.
Registering a Middleware
Now that we already know how to create our own custom
components, how do we use it?
It`s simple, in the Startup
class there is a method called Configured
which is responsible to setup how the application will handle requests.
This method has a parameter of type IApplicationBuilder, that is the object we use to register our
components.
See example below:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseMiddleware<ContentMiddleware>();
app.UseMiddleware<RequestEditMiddleware>();
app.UseMiddleware<ShortCircuitMiddleware>();
app.UseHttpsRedirection();
app.UseMvc();
}
There is a more elegant way to register the components, for
that we need to create some extension methods.
See below:
public static class MiddlewareExtensions
{
public static
IApplicationBuilder UseContentMiddleware(this IApplicationBuilder app)
{
return app.UseMiddleware<ContentMiddleware>();
}
public static
IApplicationBuilder UseRequestEditMiddleware(this IApplicationBuilder app)
{
return app.UseMiddleware<RequestEditMiddleware>();
}
public static
IApplicationBuilder UseShortCircuitMiddleware(this IApplicationBuilder app)
{
return app.UseMiddleware<ShortCircuitMiddleware>();
}
}
After creating the extension methods all we have to do is
register the components using it.
public void
ConfigureDevelopment(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseContentMiddleware();
app.UseRequestEditMiddleware();
app.UseShortCircuitMiddleware();
app.UseHttpsRedirection();
app.UseMvc();
}
No comments:
Post a Comment