如何在没有HttpClientFactory的情况下向HttpClient添加多个HttpMessageHandler

时间:2016-03-17 16:41:37

标签: c# .net dotnet-httpclient

我有一个使用HttpClient来发送网络请求的控制台应用程序。

var client = new HttpClient();

我尝试向其中添加多个HttpMessageHandlerDelegatingHandler的自定义实现,但是constructor for 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());

我看过source for HttpClientFactory并且似​​乎没有任何东西可以在.NET 4.0中编译,但是没有在我自己的工厂里滚动(&#3}} #34;灵感来自微软的源代码),有没有办法手动将许多HTTP消息处理程序添加到HttpClient

3 个答案:

答案 0 :(得分:13)

DelegatingHandler为内部处理程序提供了protected constructor that takes a handler。如果您可以控制所有自定义处理程序,我认为您可以添加一个调用受保护构造函数的公共构造函数,如:

ctime()

并将它们链接起来:

public class CustomHandler : DelegatingHandler
{
    public CustomHandler(HttpMessageHandler innerHandler) : base(innerHandler)
    {
    }
}

答案 1 :(得分:5)

我认为你可以做这样的事情:

  my topic = new Topic(); // Topic is the model
  topic.id = '123'; // my univocal id, !== _id
  topic.author = 'Marco';
  ...

  Topic.findOne({ id: topic.id }, function(err, doc) {
    if (err) {
      console.error('topic', topic.id, 'could not be searched:', err);
      return false;
    }
    var now = new Date();
    if (doc) { // old document
      topic.updatedAt = now;
    } else { // new document
      topic.insertedAt = now;
    }
    topic.save(function(err) {
      if (err) {
        console.error('topic', topic.id, 'could not be saved:', err);
        return false;
      }
      console.log('topic', topic.id, 'saved successfully');
      return true;
    });
  });

因此,您不需要为链接目的创建CustomHandler。 这确实是DelegatingHandler的目的。

答案 2 :(得分:1)

要在.Net 4.0平台上实现控制台应用程序,最好的解决方案是将httpConfiguration传递给您的webapi库,或者如果您不持有WebAPI代码,只需将此代码写入webhost asp.net应用程序的global.ascx文件中

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

   }

在您的控制台应用程序中,放置您的虚拟主机托管webapi

   private const string APiUri="http://localhost/api/get"
   using(HttpClient cleint=new HttpClient()){
     var response await cleint.GetAsync(ApiUri);
    ....
               }