web-dev-qa-db-fra.com

Comment ajouter plusieurs HttpMessageHandler à HttpClient sans HttpClientFactory

J'ai une application console qui utilise HttpClient pour effectuer des requêtes Web.

var client = new HttpClient();

J'essaie d'y ajouter plusieurs HttpMessageHandler (implémentations personnalisées de DelegatingHandler , vraiment) mais le constructeur pour HttpClient ne prend qu'un seul - HttpMessageHandler .

class LoggingHandler : DelegatingHandler { //... }
class ResponseContentProcessingHandler : DelegatingHandler { //... }

c'est acceptable...

var client = new HttpClient(new LoggingHandler()); // OK

mais cela ne compile pas:

var client = new HttpClient(
                new LoggingHandler(), 
                new ResponseContentProcessingHandler()); // Sadness

Étant donné que je cible .NET 4.0, je ne peux pas utiliser HttpClientFactory , c'est ainsi que la solution à ce problème est couramment expliquée:

HttpClient client = HttpClientFactory.Create(
                       new LoggingHandler(),
                       new ResponseContentProcessingHandler());

Parce que je suis juste dans une application console, plutôt que dans une application ASP.NET, je ne peux pas faire cela non plus:

GlobalConfiguration.Configuration
                   .MessageHandlers
                   .Add(new LoggingHandler()
                   .Add(new ResponseContentProcessingHandler());

J'ai regardé la source pour HttpClientFactory et il ne semble pas y avoir quoi que ce soit qui ne compilerait pas dans .NET 4.0, mais à court de rouler ma propre usine ("inspiré" par Microsoft code source), existe-t-il un moyen d'ajouter manuellement de nombreux gestionnaires de messages HTTP au HttpClient ?

14
Jeff

Je pense que vous pouvez simplement faire quelque chose comme ça:

var loggingHandler = new LoggingHandler();
var responseContentProcessingHandler =  new ResponseContentProcessingHandler();
loggingHandler.InnerHandler = responseContentProcessingHandler;
var client = new HttpClient(loggingHandler);

Pour que vous n'ayez pas besoin de créer un CustomHandler uniquement pour le chaînage. C'est vraiment le but de DelegatingHandler.

7
liuhongbo

DelegatingHandler a un constructeur protégé qui prend un gestionnaire pour le gestionnaire interne. Si vous avez le contrôle sur tous vos gestionnaires personnalisés, je pense que vous pouvez ajouter un constructeur public qui appelle le constructeur protégé, comme:

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

et les enchaîner ainsi:

var client = new HttpClient(
    new CustomHandler(
        new OtherCustomerHandler(
            new HttpClientHandler()
        )
    )
);
16
Jeff Shepler

Pour réaliser avec l'application console sur la plate-forme .Net 4.0, la meilleure solution possible est de passer httpConfiguration à votre bibliothèque webapi ou si vous ne détenez pas le code WebAPI, écrivez simplement ce code dans le fichier global.ascx de l'application 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());

   }

Dans votre application console, placez l'URI de votre hébergeur webapi

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