Middleware is a software that's assembled into an app pipeline to handle requests and responses. Each component:
- Chooses whether to pass the request to the next component in the pipeline.
- Can perform work before and after the next component in the pipeline.
Request delegates are used to build the request pipeline and are configured using Run , Map and Use extension methods.
The ASP.Net Core
request pipeline consists of a sequence of request delegates, called one after the other. The following diagram from Microsoft docs demonstrates the concept. The thread of execution follows the black arrows.
Create custom middleware
Lets consider the following middleware example configured in the Startup.cs
which sets the culture for the current request from Claims
of HttpContext
.
public class Startup
{
public void Configure(IApplicationBuilder app)
{
app.Use(async (context, next) =>
{
var claims = context?.User?.Claims?.ToList();
// Get cultureId out of claims.
// If not set then fallback to en-US
var cultureId = claims.
?FirstOrDefault(claim => claim.Type == "CultureId")
?.Value
?? "en-US";
// Retrieve a read-only instance of culture
// using the specified culture name
var cultureInfo = CultureInfo.GetCultureInfo(cultureId);
CultureInfo.CurrentCulture = cultureInfo;
CultureInfo.CurrentUICulture = cultureInfo;
// Call the next delegate/middleware in the pipeline
await next();
});
}
}
Now we can extract the above middleware delegate into a class. Our middleware class must include:
- A public constructor with a parameter of type RequestDelegate
- A public method named
Invoke
orInvokeAsync
. This method must return aTask
accept a first parameter of typeHttpContext
public class TokenCultureMiddleware
{
private readonly RequestDelegate _next;
public TokenCultureMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
var claims = context?.User?.Claims?.ToList();
// Get cultureId out of claims.
// If not set then fallback to en-US
var cultureId = claims.
?FirstOrDefault(claim => claim.Type == "CultureId")
?.Value
?? "en-US";
// Retrieve a read-only instance of culture
// using the specified culture name
var cultureInfo = CultureInfo.GetCultureInfo(cultureId);
CultureInfo.CurrentCulture = cultureInfo;
CultureInfo.CurrentUICulture = cultureInfo;
// Call the next delegate/middleware in the pipeline
await _next.Invoke(context);
}
}
Middleware extension method
Last we can create a middleware extension method and call our custom middleware from Startup.Configure
public static class TokenCultureMiddlewareExtensions
{
public static IApplicationBuilder UseTokenCulture(
this IApplicationBuilder builder)
{
return builder.UseMiddleware<TokenCultureMiddleware>();
}
}
And in Startup.Configure
public class Startup
{
public void Configure(IApplicationBuilder app)
{
// Call our extension method
app.UseTokenCulture();
}
}