Les Middlewares
Dans ASP.NET Core, le pipeline de traitement des requêtes (Request Pipeline) est composé d’une série de composants appelés Middlewares.
Chaque middleware intercepte la requête HTTP entrant, peut effectuer des opérations avant et après le middleware suivant, et décide de passer ou non la requête au suivant.
Le Pipeline
Imaginez le pipeline comme une série de couches d’oignon ou de filtres.
- La requête arrive.
- Elle traverse le Middleware 1.
- Elle traverse le Middleware 2.
- …
- Elle atteint le Endpoint (votre Controller).
- Le Controller génère une réponse.
- La réponse repasse par le Middleware 2 (en sens inverse).
- La réponse repasse par le Middleware 1.
- La réponse est envoyée au client.

Utilisation standard
Vous utilisez déjà des middlewares sans le savoir dans Program.cs :
var app = builder.Build();
// Middleware de redirection HTTPS
app.UseHttpsRedirection();
// Middleware d'autorisation
app.UseAuthorization();
// Middleware qui mappe les controllers aux routes
app.MapControllers();
app.Run();
L’ordre de déclaration dans Program.cs est CRUCIAL. Si UseAuthorization est placé avant UseAuthentication (qui décode le user), l’autorisation échouera car l’utilisateur ne sera pas encore connu.
Créer un Middleware personnalisé
Pour des besoins spécifiques (Logging global, Gestion d’erreur globale, Headers de sécurité), on peut créer nos propres middlewares.
Un middleware est généralement une classe qui possède :
- Un constructeur prenant un
RequestDelegate(le pointeur vers le middleware suivant). - Une méthode
InvokeAsyncprenant leHttpContext.
public class SimpleLoggerMiddleware
{
private readonly RequestDelegate _next;
public SimpleLoggerMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
// Avant le controller : On log la requête
Console.WriteLine($"Request: {context.Request.Method} {context.Request.Path}");
// On passe la main au middleware suivant
await _next(context);
// Après le controller : On log le status code
Console.WriteLine($"Response: {context.Response.StatusCode}");
}
}
Enregistrement
Pour utiliser ce middleware, on l’ajoute dans Program.cs :
app.UseMiddleware<SimpleLoggerMiddleware>();
Cas d’usage : Gestion globale des erreurs
Plutôt que de mettre des try/catch dans chaque méthode de vos controllers, vous pouvez utiliser un middleware qui englobe toute l’exécution.
Si une exception “remonte” jusqu’au middleware sans être attrapée, le middleware peut l’intercepter, formatter une belle réponse JSON d’erreur, et renvoyer un code HTTP approprié (500, 400, 404).
Cela permet de garder vos controllers propres et focalisés sur la logique métier.
Changer le code de retour et le contenu depuis un middleware
Voici comment fonctionne le code ci-dessous :
Dans un middleware, vous pouvez modifier le code de retour HTTP (StatusCode) et le contenu de la réponse. Par exemple, ici :
context.Response.StatusCode = statusCode;: fixe le code HTTP de réponse (ex : 200, 400, 500, …).context.Response.ContentType = "application/json";: indique que la réponse sera du JSON.await context.Response.WriteAsync(...): écrit le contenu dans la réponse. Ici on utiliseJsonSerializer.Serialize(...)pour transformer un objet .NET en JSON.
Ce modèle permet donc de gérer proprement les erreurs côté serveur :
- On choisit le code de retour HTTP,
- On construit une réponse structurée (souvent avec un message, un code d’erreur, etc.),
- On l’envoie au format JSON à l’utilisateur.
C’est la base de la gestion d’erreur globale par middleware, pour retourner des messages d’erreur uniformisés à toutes les erreurs non attrapées ailleurs.
// On configure les options de sérialisation pour avoir un JSON en camelCase comme dans les contrôleurs
var option = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
context.Response.StatusCode = statusCode;
context.Response.ContentType = "application/json";
await context.Response.WriteAsync(
JsonSerializer.Serialize(new MaClasse(1, "abc"), option)
);
Le code ci-dessus est un exemple de comment on peut changer le code de retour et le contenu de la réponse depuis un middleware.