Middleware, Routing & Configuration
ASP.NET Core: Middleware, Routing & Configuration ASP.NET Core is a cross-platform, high-performance framework for building web APIs, web apps, and microservice…
ASP.NET Core: Middleware, Routing & Configuration
ASP.NET Core is a cross-platform, high-performance framework for building web APIs, web apps, and microservices. The request pipeline is built from middleware components chained together.
Program.cs — App Bootstrap
var builder = WebApplication.CreateBuilder(args);
// Register services
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("Default")));
builder.Services.AddScoped<IArticleService, ArticleService>();
builder.Services.AddSingleton<ICacheService, RedisCacheService>();
var app = builder.Build();
// Middleware pipeline (order matters)
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication(); // must be before UseAuthorization
app.UseAuthorization();
app.MapControllers();
app.Run();Middleware
// Custom middleware (class-based)
public class RequestLoggingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<RequestLoggingMiddleware> _logger;
public RequestLoggingMiddleware(RequestDelegate next, ILogger<RequestLoggingMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task InvokeAsync(HttpContext context)
{
var watch = Stopwatch.StartNew();
_logger.LogInformation("Request {Method} {Path}", context.Request.Method, context.Request.Path);
await _next(context); // call next middleware
watch.Stop();
_logger.LogInformation("Response {StatusCode} in {Elapsed}ms",
context.Response.StatusCode, watch.ElapsedMilliseconds);
}
}
// Extension method for clean registration
public static class MiddlewareExtensions
{
public static IApplicationBuilder UseRequestLogging(this IApplicationBuilder app)
=> app.UseMiddleware<RequestLoggingMiddleware>();
}
// Use in Program.cs
app.UseRequestLogging();
// Inline middleware (simple cases)
app.Use(async (context, next) =>
{
context.Response.Headers["X-Content-Type-Options"] = "nosniff";
await next(context);
});
// Terminal middleware (no next call)
app.Run(async context =>
{
await context.Response.WriteAsync("Fallback response");
});Configuration
// appsettings.json
// {
// "ConnectionStrings": { "Default": "Server=...;Database=..." },
// "JwtSettings": { "Secret": "...", "ExpiryMinutes": 60 },
// "FeatureFlags": { "NewDashboard": true }
// }
// Bind to strongly-typed class
public class JwtSettings
{
public string Secret { get; set; } = string.Empty;
public int ExpiryMinutes { get; set; } = 60;
}
// In Program.cs
builder.Services.Configure<JwtSettings>(
builder.Configuration.GetSection("JwtSettings"));
// In a service
public class TokenService
{
private readonly JwtSettings _settings;
public TokenService(IOptions<JwtSettings> options)
{
_settings = options.Value;
}
}
// Read directly
var secret = builder.Configuration["JwtSettings:Secret"];
var connStr = builder.Configuration.GetConnectionString("Default");
// Environment overrides: appsettings.Development.json > appsettings.json
// Env vars override JSON: JWTSET__SECRET=value (double underscore = colon)
// Secrets manager (dev): dotnet user-secrets set "JwtSettings:Secret" "value"Routing
// Attribute routing (controllers)
[ApiController]
[Route("api/[controller]")] // → api/articles
public class ArticlesController : ControllerBase
{
[HttpGet] // GET api/articles
[HttpGet("{id:int}")] // GET api/articles/42 (with constraint)
[HttpGet("search")] // GET api/articles/search
[HttpGet("{id}/comments")] // GET api/articles/42/comments
[HttpPost] // POST api/articles
[HttpPut("{id}")] // PUT api/articles/42
[HttpDelete("{id}")] // DELETE api/articles/42
}
// Route constraints
// {id:int} — integer
// {id:guid} — GUID
// {name:alpha} — letters only
// {age:int:min(1):max(120)}
// {slug:regex(^[a-z0-9-]+$)}