共用方式為


ASP.NET Web API 中的 HttpClient 訊息處理常式

訊息處理常式是接收 HTTP 要求的類別,並傳回 HTTP 回應。

一般而言,一系列的訊息處理常式會鏈結在一起。 第一個處理常式會接收 HTTP 要求、執行一些處理,並將要求提供給下一個處理常式。 在某些時候,會建立回應並備份鏈結。 此模式稱為委派處理常式。

鏈結在一起的訊息處理常式圖表,說明接收 H T T P 要求並傳回 H T T P 回應的流程。

在用戶端上,HttpClient 類別會使用訊息處理常式來處理要求。 預設處理常式為 HttpClientHandler,它會透過網路傳送要求,並從伺服器取得回應。 您可以將自訂訊息處理常式插入用戶端管線:

將自訂訊息處理常式插入用戶端管線的流程圖表。顯示 h t t p 用戶端類別,該類別會使用訊息處理常式來處理要求。

注意

ASP.NET Web API 也會在伺服器端使用訊息處理常式。 如需其他資訊,請參閱 HTTP 訊息處理常式

自訂訊息處理常式

若要撰寫自訂訊息處理常式,請衍生自 System.Net.Http.DelegatingHandler 並覆寫 SendAsync 方法。 這是方法簽名:

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

方法會採用 HttpRequestMessage 作為輸入,並以非同步方式傳回 HttpResponseMessage。 一般實作會執行下列操作:

  1. 處理要求訊息。
  2. 呼叫 base.SendAsync 以將要求傳送至內部處理常式。
  3. 內部處理常式會傳回回應訊息。 (此步驟是非同步的。)
  4. 處理回應並將它傳回給呼叫端。

下列範例顯示將自訂標頭新增至傳出要求的訊息處理常式:

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

base.SendAsync 的呼叫是非同步的。 如果處理常式在此呼叫之後執行任何工作,請使用 await 關鍵字在方法完成之後繼續執行。 下列範例顯示記錄錯誤碼的處理常式。 記錄本身並不十分有趣,但此範例示範如何取得處理常式內的回應。

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

將訊息處理常式新增至用戶端管線

若要將自訂處理常式新增至 HttpClient,請使用 HttpClientFactory.Create 方法:

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

訊息處理常式會依照您傳遞至 Create 方法的順序呼叫。 因為處理常式是巢狀的,所以回應訊息會以另一個方向移動。 也就是說,最後一個處理常式是第一個取得回應訊息的處理常式。