Dans les applications ASP.NET modernes, en particulier avec l'arrivée des minimal APIs dans .NET 9, la configuration des HTTPClients pour les appels externes est à la fois puissante et flexible. L'un des principaux atouts est la possibilité de créer des HTTPClients nommés et d'étendre leur comportement à l'aide de message handlers. Dans cet article, nous allons examiner deux types de message handlers :
- PrimaryMessageHandlers : offrent un contrôle sur le transport sous-jacent (par exemple, activer TLS1.3, personnaliser la validation du certificat SSL).
- DelegatingHandlers : permettent de modifier ou d'inspecter les requêtes et réponses HTTP au niveau de l'application (par exemple, définir la version HTTP, journaliser, ajouter des en-têtes personnalisés).
Ci-dessous, nous verrons comment chacun peut être utilisé dans des services ASP.NET minimal API avec des exemples de code.
HTTPClients nommés dans des services Minimal API
L'injection de dépendances d'ASP.NET facilite l'enregistrement de HTTPClients nommés. Vous pouvez configurer différents clients avec des comportements différents, puis les récupérer via IHttpClientFactory.
Exemple d'enregistrement :
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpClient("MyClient");
// Add other named clients
var app = builder.Build();
app.MapGet("/", async (IHttpClientFactory clientFactory) =>
{
var client = clientFactory.CreateClient("MyClient");
var response = await client.GetAsync("https://example.com");
return await response.Content.ReadAsStringAsync();
});
app.Run();
PrimaryMessageHandlers : personnalisation au niveau du transport
Le PrimaryMessageHandler est le handler sous-jacent qui gère le transport réseau. En le configurant, vous pouvez contrôler des détails bas niveau comme les protocoles TLS et la validation du certificat SSL. C'est particulièrement utile lorsque vous devez imposer des exigences de sécurité spécifiques.
Exemple : configuration de TLS1.3 et validation personnalisée du certificat SSL
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpClient("MyPrimaryClient")
.ConfigurePrimaryHttpMessageHandler(() => new SocketsHttpHandler
{
SslOptions = new SslClientAuthenticationOptions
{
// Enforce TLS1.3 for secure communication
EnabledSslProtocols = System.Security.Authentication.SslProtocols.Tls13,
RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
{
// Custom logic to validate SSL certificate can be added here
Console.WriteLine("Primary handler: Validating SSL certificate.");
return true; // Or implement proper validation logic
}
}
});
// Configure other named clients
var app = builder.Build();
app.MapGet("/primary", async (IHttpClientFactory clientFactory) =>
{
var client = clientFactory.CreateClient("MyPrimaryClient");
var response = await client.GetAsync("https://example.com");
return await response.Content.ReadAsStringAsync();
});
app.Run();
DelegatingHandlers : personnalisation au niveau de l'application
Les DelegatingHandlers se placent dans le pipeline HTTPClient et vous permettent de modifier la requête ou la réponse. Ils sont idéaux pour des tâches comme la journalisation, l'ajout d'en-têtes personnalisés ou l'application de protocoles au niveau applicatif comme HTTP/2.
Exemple : Delegating Handler personnalisé pour imposer HTTP/2
public class CustomDelegatingHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
// Enforce HTTP/2 for the outgoing request
request.Version = HttpVersion.Version20;
Console.WriteLine("CustomDelegatingHandler: Request is set to use HTTP/2.");
return await base.SendAsync(request, cancellationToken);
}
}
Leçon retenue
Essayer d'utiliser l'approche modulaire légère des DelegatingHandlers pour appliquer une configuration au niveau du transport ne fonctionne pas. Modifier le InnerHandler d'un DelegatingHandler provoque une exception :
System.InvalidOperationException: The 'InnerHandler' property must be null. 'DelegatingHandler' instances provided to 'HttpMessageHandlerBuilder' must not be reused or cached.
Cela est dû au fait que modifier le InnerHandler casserait le pipeline des handlers. Encapsuler la requête de chaque DelegatingHandler dans un nouveau HttpMessageInvoker contournera l'exception, mais cassera toujours la chaîne.
TL;DR : n'utilisez pas les DelegatingHandlers pour le niveau transport.
Enregistrer le handler avec un HTTPClient nommé
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddTransient<CustomDelegatingHandler>();
builder.Services.AddHttpClient("MyDelegatingClient")
.AddHttpMessageHandler<CustomDelegatingHandler>();
var app = builder.Build();
app.MapGet("/delegating", async (IHttpClientFactory clientFactory) =>
{
var client = clientFactory.CreateClient("MyDelegatingClient");
var response = await client.GetAsync("https://example.com");
return await response.Content.ReadAsStringAsync();
});
app.Run();
Conclusion
En tirant parti à la fois des DelegatingHandlers et des PrimaryMessageHandlers, vous pouvez contrôler finement la communication HTTP dans vos services ASP.NET Core minimal API :
- Les clients HTTP nommés offrent une manière modulaire de configurer des clients HTTP pour différentes cibles.
- Les PrimaryMessageHandlers offrent un point d'accès aux personnalisations au niveau du transport (par exemple, imposer TLS1.3, gérer la validation des certificats SSL).
- Les DelegatingHandlers permettent de manipuler les comportements au niveau applicatif (par exemple, imposer HTTP/2, ajouter des en-têtes).
Cette approche par couches permet des interactions HTTP robustes, sécurisées et flexibles, adaptées aux besoins spécifiques de votre application. Bon codage !
Besoin d'aide ?
Vous souhaitez configurer et sécuriser au mieux les clients HTTP de vos applications ASP.NET Core, mais vous hésitez sur l'implémentation ? Nous pouvons vous aider. Contactez-nous via notre page de contact et nous travaillerons ensemble pour professionnaliser votre intégration API.




