Skip to main content

Exercise 3: Custom Middleware

Objective

Create custom middleware to log requests and measure response times.

Implementation

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 startTime = DateTime.UtcNow;
var requestId = Guid.NewGuid().ToString();

_logger.LogInformation(
"[{RequestId}] {Method} {Path} started",
requestId,
context.Request.Method,
context.Request.Path);

await _next(context);

var elapsed = DateTime.UtcNow - startTime;

_logger.LogInformation(
"[{RequestId}] {Method} {Path} completed in {ElapsedMs}ms with status {StatusCode}",
requestId,
context.Request.Method,
context.Request.Path,
elapsed.TotalMilliseconds,
context.Response.StatusCode);

context.Response.Headers.Add("X-Response-Time", elapsed.TotalMilliseconds.ToString());
context.Response.Headers.Add("X-Request-Id", requestId);
}
}

// Extension method
public static class MiddlewareExtensions
{
public static IApplicationBuilder UseRequestLogging(
this IApplicationBuilder builder)
{
return builder.UseMiddleware<RequestLoggingMiddleware>();
}
}

// Usage
app.UseRequestLogging();

Challenge Tasks

  1. Add API key validation middleware
  2. Create exception handling middleware
  3. Implement rate limiting middleware (simple counter)
  4. Add request/response body logging

Expected Outcome

  • Custom middleware that logs all requests
  • Response time header added to responses
  • Understanding of middleware execution order