Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Обработчик сообщений — это класс, который получает HTTP-запрос и возвращает HTTP-ответ.
Как правило, ряд обработчиков сообщений объединяется. Первый обработчик получает HTTP-запрос, выполняет некоторую обработку и передает запрос следующему обработчику. В какой-то момент создается ответ и выполняется резервное копирование цепочки. Этот шаблон называется делегированным обработчиком.
На стороне клиента класс HttpClient использует обработчик сообщений для обработки запросов. Обработчик по умолчанию — HttpClientHandler, который отправляет запрос по сети и получает ответ с сервера. Можно вставить пользовательские обработчики сообщений в клиентский конвейер:
Замечание
ASP.NET веб-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 . Поскольку обработчики вложены друг в друга, сообщение ответа перемещается в противоположном направлении. То есть последний обработчик первым получает ответное сообщение.