消息处理程序是接收 HTTP 请求并返回 HTTP 响应的类。
通常,一系列消息处理程序链接在一起。 第一个处理程序接收 HTTP 请求,执行一些处理,并向下一个处理程序提供请求。 在某个时刻,响应被创建,并沿着链条向上返回。 此模式称为 委派 处理程序。
在客户端上, HttpClient 类使用消息处理程序来处理请求。 默认处理程序是 HttpClientHandler,该处理程序通过网络发送请求并从服务器获取响应。 可以将自定义消息处理程序插入客户端管道:
注释
ASP.NET Web API 还使用服务器端的消息处理程序。 有关详细信息,请参阅 HTTP 消息处理程序。
自定义消息处理程序
若要编写自定义消息处理程序,请派生自 System.Net.Http.DelegatingHandler 并重写 SendAsync 方法。 下面是方法签名:
Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken);
该方法采用 HttpRequestMessage 作为输入,并异步返回 HttpResponseMessage。 典型的实现执行以下操作:
- 处理请求消息。
- 调用
base.SendAsync以将请求发送到内部处理程序。 - 内部处理程序返回响应消息。 (此步骤是异步的。
- 处理响应并将其返回到调用方。
以下示例显示了向传出请求添加自定义标头的消息处理程序:
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 方法的顺序被调用。 由于处理程序是嵌套的,因此响应消息会向另一个方向传输。 也就是说,最后一个处理程序是第一个获取响应消息的处理程序。