Как добавить несколько HttpMessageHandler в HttpClient без HttpClientFactory
У меня есть консольное приложение, которое использует HttpClient для выполнения веб-запросов.
var client = new HttpClient();
Я пытаюсь добавить несколько HttpMessageHandler к нему (на самом деле пользовательские реализации DelegatingHandler), но конструктор для HttpClient принимает только один HttpMessageHandler.
class LoggingHandler : DelegatingHandler { //... }
class ResponseContentProcessingHandler : DelegatingHandler { //... }
это нормально...
var client = new HttpClient(new LoggingHandler()); // OK
но это не компилируется:
var client = new HttpClient(
new LoggingHandler(),
new ResponseContentProcessingHandler()); // Sadness
Поскольку я нацеливаюсь на .NET 4.0, я не могу использовать HttpClientFactory, как обычно объясняется решение этой проблемы:
HttpClient client = HttpClientFactory.Create(
new LoggingHandler(),
new ResponseContentProcessingHandler());
Поскольку я просто в консольном приложении, а не в приложении ASP.NET, я тоже не могу сделать это:
GlobalConfiguration.Configuration
.MessageHandlers
.Add(new LoggingHandler()
.Add(new ResponseContentProcessingHandler());
Я посмотрел на исходник для HttpClientFactory, и там, похоже, нет ничего такого, что не скомпилировалось бы в .NET 4.0, но если не считать развертывания моей собственной фабрики ("вдохновленной" Исходный код Microsoft), есть ли способ вручную добавить множество обработчиков HTTP-сообщений в HttpClient?
Ответы
Ответ 1
Я думаю, вы можете просто сделать что-то вроде этого:
var loggingHandler = new LoggingHandler();
var responseContentProcessingHandler = new ResponseContentProcessingHandler();
loggingHandler.InnerHandler = responseContentProcessingHandler;
var client = new HttpClient(loggingHandler);
Так что вам не нужно создавать CustomHandler только для цепочки.
Это действительно цель делегированияHandler.
Ответ 2
DelegatingHandler имеет защищенный конструктор , который принимает обработчик для внутреннего обработчика. Если у вас есть контроль над всеми вашими пользовательскими обработчиками, я думаю, вы можете добавить открытый конструктор, который вызывает защищенный конструктор, например:
public class CustomHandler : DelegatingHandler
{
public CustomHandler(HttpMessageHandler innerHandler) : base(innerHandler)
{
}
}
и соедините их так:
var client = new HttpClient(
new CustomHandler(
new OtherCustomerHandler(
new HttpClientHandler()
)
)
);
Ответ 3
Чтобы достичь с помощью приложения Console на платформе .NET 4.0, наилучшим возможным решением является передать httpConfiguration в вашу библиотеку webapi или если вы не храните код WebAPI, просто напишите этот код в файле global.ascx приложения webhost asp.net
protected void Application_Start(object sender, EventArgs e)
{
var config = GlobalConfiguration.Configuration;
WebAPIConfig.Configure(config);
}
//Code that will configure all message handlers in webapi
public static void Configure(HttpConfiguration configure)
{
configure.MessageHandlers.Add(new xyzhandler());
configure.MessageHandlers.Add(new ABCHandler());
}
В своем консольном приложении разместите uri своего веб-хостинга webapi
private const string APiUri="http://localhost/api/get"
using(HttpClient cleint=new HttpClient()){
var response await cleint.GetAsync(ApiUri);
....
}