HttpClient-üzenetkezelők ASP.NET Webes API-ban

Az üzenetkezelő egy olyan osztály, amely HTTP-kérést fogad, és HTTP-választ ad vissza.

Az üzenetkezelők általában össze vannak láncolva. Az első kezelő HTTP-kérést kap, némi feldolgozást végez, és átadja a kérést a következő kezelőnek. Egy bizonyos ponton létrejön a válasz, és visszatér a lánc mentén. Ezt a mintát delegáló kezelőnek nevezzük.

Az üzenetkezelők összeláncolt diagramja, amely szemlélteti a H T T P kérés fogadásának és a H T T P-válasz visszaadásának folyamatát.

Az ügyféloldalon a HttpClient-osztály egy üzenetkezelőt használ a kérések feldolgozásához. Az alapértelmezett kezelő a HttpClientHandler, amely elküldi a kérést a hálózaton keresztül, és megkapja a választ a kiszolgálótól. Egyéni üzenetkezelőket szúrhat be az ügyfélfolyamatba:

Egyéni üzenetkezelők ügyfélfolyamatba való beszúrásának folyamatábraja. A h t t p ügyfélosztályt jeleníti meg, amely üzenetkezelőt használ a kérések feldolgozásához.

Megjegyzés:

ASP.NET Web API a kiszolgálóoldalon is használ üzenetkezelőket. További információ: HTTP-üzenetkezelők.

Egyéni üzenetkezelők

Egyéni üzenetkezelő írásához származtassa a System.Net.Http.DelegatingHandler osztályból, és bírálja felül a SendAsync metódust. A metódus aláírása a következő:

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

A metódus bemenetként egy HttpRequestMessage értéket használ, és aszinkron módon egy HttpResponseMessage értéket ad vissza. Egy tipikus implementáció a következőket teszi:

  1. A kérési üzenet feldolgozása.
  2. Hívás base.SendAsync a kérés belső kezelőnek való elküldéséhez.
  3. A belső kezelő válaszüzenetet ad vissza. (Ez a lépés aszinkron.)
  4. Dolgozza fel a választ, és küldje vissza a hívónak.

Az alábbi példa egy üzenetkezelőt mutat be, amely egy egyéni fejlécet ad hozzá a kimenő kéréshez:

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);
    }
}

Az base.SendAsync hívás aszinkron. Ha a kezelő a hívás után bármilyen munkát végez, a várt kulcsszóval folytathatja a végrehajtást a metódus befejeződése után. Az alábbi példa egy hibakódokat naplózó kezelőt mutat be. Maga a naplózás nem túl érdekes, de a példa bemutatja, hogyan juthat hozzá a válaszhoz a kezelőn belül.

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);
    }
}

Üzenetkezelők hozzáadása az ügyfélfolyamathoz

Ha egyéni kezelőket szeretne hozzáadni a HttpClienthez, használja a HttpClientFactory.Create metódust:

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

Az üzenetkezelőket a rendszer abban a sorrendben hívja meg, hogy átadja őket a Létrehozás metódusnak. Mivel a kezelők beágyazottak, a válaszüzenet a másik irányba halad. Vagyis az utolsó kezelő kapja meg elsőként a válaszüzenetet.