Gestionnaires de messages HttpClient dans API Web ASP.NET

Un gestionnaire de messages est une classe qui reçoit une requête HTTP et retourne une réponse HTTP.

En règle générale, une série de gestionnaires de messages sont chaînés. Le premier gestionnaire reçoit une requête HTTP, effectue un traitement et transmet la requête au gestionnaire suivant. À un moment donné, la réponse est créée et remonte la chaîne. Ce modèle est appelé gestionnaire de délégation .

Diagramme des gestionnaires de messages chaînés, illustrant le processus de réception d’une demande HTT et de retour d’une réponse HT P.

Côté client, la classe HttpClient utilise un gestionnaire de messages pour traiter les demandes. Le gestionnaire par défaut est HttpClientHandler, qui envoie la requête sur le réseau et obtient la réponse du serveur. Vous pouvez insérer des gestionnaires de messages personnalisés dans le pipeline client :

Diagramme du processus d’insertion de gestionnaires de messages personnalisés dans le pipeline client. Affiche la classe client h t t p qui utilise un gestionnaire de messages pour traiter les demandes.

Notes

API Web ASP.NET utilise également des gestionnaires de messages côté serveur. Pour plus d’informations, consultez Gestionnaires de messages HTTP.

Gestionnaires de messages personnalisés

Pour écrire un gestionnaire de messages personnalisé, dérivez de System.Net.Http.DelegatingHandler et remplacez la méthode SendAsync . Voici la signature de méthode :

Task<HttpResponseMessage> SendAsync(
    HttpRequestMessage request, CancellationToken cancellationToken);

La méthode prend un HttpRequestMessage comme entrée et retourne de façon asynchrone un HttpResponseMessage. Une implémentation classique effectue les opérations suivantes :

  1. Traitez le message de demande.
  2. Appelez base.SendAsync pour envoyer la demande au gestionnaire interne.
  3. Le gestionnaire interne retourne un message de réponse. (Cette étape est asynchrone.)
  4. Traitez la réponse et retournez-la à l’appelant.

L’exemple suivant montre un gestionnaire de messages qui ajoute un en-tête personnalisé à la requête sortante :

class MessageHandler1 : DelegatingHandler
{
    private int _count = 0;

    protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
    {
        System.Threading.Interlocked.Increment(ref _count);
        request.Headers.Add("X-Custom-Header", _count.ToString());
        return base.SendAsync(request, cancellationToken);
    }
}

L’appel à base.SendAsync est asynchrone. Si le gestionnaire effectue un travail après cet appel, utilisez le mot clé await pour reprendre l’exécution une fois la méthode terminée. L’exemple suivant montre un gestionnaire qui journalise les codes d’erreur. La journalisation elle-même n’est pas très intéressante, mais l’exemple montre comment obtenir la réponse à l’intérieur du gestionnaire.

class LoggingHandler : DelegatingHandler
{
    StreamWriter _writer;

    public LoggingHandler(Stream stream)
    {
        _writer = new StreamWriter(stream);
    }

    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
    {
        var response = await base.SendAsync(request, cancellationToken);

        if (!response.IsSuccessStatusCode)
        {
            _writer.WriteLine("{0}\t{1}\t{2}", request.RequestUri, 
                (int)response.StatusCode, response.Headers.Date);
        }
        return response;
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            _writer.Dispose();
        }
        base.Dispose(disposing);
    }
}

Ajout de gestionnaires de messages au pipeline client

Pour ajouter des gestionnaires personnalisés à HttpClient, utilisez la méthode HttpClientFactory.Create :

HttpClient client = HttpClientFactory.Create(new Handler1(), new Handler2(), new Handler3());

Les gestionnaires de messages sont appelés dans l’ordre dans lequel vous les transmettez à la méthode Create . Étant donné que les gestionnaires sont imbriqués, le message de réponse se déplace dans l’autre sens. Autrement dit, le dernier gestionnaire est le premier à obtenir le message de réponse.