Как добавить несколько 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);
    ....
               }