An ASP.NET Core application's workflow consist of accepting request and serving response to client. With this workflow, an application has different features / functionality like authentication, error handling or logging etc. ASP.NET Core has provided concept of middleware to implement application's features. A middleware is nothing but a C# class which is placed inside ASP.NET Core's request processing pipeline.
A middleware can perform below tasks :
- Decide whether to pass the HTTP request to the next middleware in request processing pipeline.
- Can modify the request / response before / after passing it to next middleware in pipeline.
Configuring the middleware
Middleware components are configured in Configure method of Startup.cs file. ASP.NET Core has provided some built-in middleware. Middleware can also be added via Nuget package manager or custom middleware can be added.
Below is the Startup.cs file's Configure method. All the middleware shown in this file are built-in middleware
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
Middleware ordering
Middleware components are executed in the order they are added to the pipeline and care should be taken to add the middleware in the right order otherwise the application may not function as expected. This ordering is critical for security, performance, and functionality.
Adding inline middleware using app.Use and app.Run method
Inline middleware can be added using app.use or app.Run method.
Middleware defined using app.Use may call next middleware component in the pipeline. Middlware defined using app.Run will never call subsequent middleware.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.Use(async (context, next) =>
{
await context.Response.WriteAsync("Middleware 1 using app.Use()");
await next();
});
app.Use(async (context, next) =>
{
await context.Response.WriteAsync("Middleware 2 using app.Use()");
await next();
});
app.Run(async context =>
{
await context.Response.WriteAsync("Middleware 3 using app.Run()");
// Short circuiting the pipeline
});
// This will never be called
app.Use(async (context, next) =>
{
await context.Response.WriteAsync("Middleware 4 using app.Use()");
await next();
});
}
Adding custom middleware
below is an example where a middleware is created to log the incoming request's http method
public class LogRequestMethodMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<LogRequestMethodMiddleware> _logger;
public LogRequestMethodMiddleware(RequestDelegate next,
ILogger<LogRequestMethodMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task InvokeAsync (HttpContext context)
{
_logger.LogInformation(context.Request.Method);
await _next(context);
}
}
Inside Startup.cs file
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseMiddleware<LogRequestMethodMiddleware>();
app.Run(async context =>
{
await context.Response.WriteAsync("\n Adding custom middleware");
});
}
Built-in Middleware
ASP.NET Core has some built-in middleware for common application scenario :
- Exception/error handling
- HTTPS Redirection Middleware (UseHttpsRedirection) redirects HTTP requests to HTTPS.
- Static File Middleware (UseStaticFiles) returns static files and short-circuits further request processing.
- Cookie Policy Middleware (UseCookiePolicy) conforms the app to the EU General Data Protection Regulation (GDPR) regulations.
- Routing Middleware (UseRouting) to route requests.
- Authentication Middleware (UseAuthentication) attempts to authenticate the user before they're allowed access to secure resources.
- Authorization Middleware (UseAuthorization) authorizes a user to access secure resources.
- Session Middleware (UseSession) establishes and maintains session state. If the app uses session state, call Session Middleware after Cookie Policy Middleware and before MVC Middleware.
- Endpoint Routing Middleware (UseEndpoints with MapRazorPages) to add Razor Pages endpoints to the request pipeline.