如何在 .NET Core 中使用 HttpClientHandler 和 HttpClientFactory

Posted

技术标签:

【中文标题】如何在 .NET Core 中使用 HttpClientHandler 和 HttpClientFactory【英文标题】:How to use HttpClientHandler with HttpClientFactory in .NET Core 【发布时间】:2018-06-07 18:17:14 【问题描述】:

我想使用 .NET Core 2.1 中提供的 HttpClientFactory,但我也想在创建 HttpClients 时使用 HttpClientHandler 来利用 AutomaticDecompression 属性。

我很挣扎,因为.AddHttpMessageHandler<> 需要DelegatingHandler 而不是HttpClientHandler

有谁知道如何让它工作?

谢谢, 吉姆

【问题讨论】:

【参考方案1】:

通过 HttpClientBuilder 的 ConfigurePrimaryHttpMessageHandler() 方法更恰当地定义主 HttpMessageHandler。请参阅下面的示例以配置类型化客户端。

services.AddHttpClient<TypedClient>()
    .ConfigureHttpClient((sp, httpClient) =>
    
        var options = sp.GetRequiredService<IOptions<SomeOptions>>().Value;
        httpClient.BaseAddress = options.Url;
        httpClient.Timeout = options.RequestTimeout;
    )
    .SetHandlerLifetime(TimeSpan.FromMinutes(5))
    .ConfigurePrimaryHttpMessageHandler(x => new HttpClientHandler() 
    
        AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
    )
    .AddHttpMessageHandler(sp => sp.GetService<SomeCustomHandler>().CreateAuthHandler())
    .AddPolicyHandlerFromRegistry(PollyPolicyName.HttpRetry)
    .AddPolicyHandlerFromRegistry(PollyPolicyName.HttpCircuitBreaker);

您还可以通过使用 Polly 库的特殊构建器方法来定义错误处理策略。在此示例中,策略应预定义并存储到策略注册服务中。

public static IServiceCollection AddPollyPolicies(
    this IServiceCollection services, 
    Action<PollyPoliciesOptions> setupAction = null)

    var policyOptions = new PollyPoliciesOptions();
    setupAction?.Invoke(policyOptions);

    var policyRegistry = services.AddPolicyRegistry();

    policyRegistry.Add(
        PollyPolicyName.HttpRetry,
        HttpPolicyExtensions
            .HandleTransientHttpError()
            .WaitAndRetryAsync(
                policyOptions.HttpRetry.Count,
                retryAttempt => TimeSpan.FromSeconds(Math.Pow(policyOptions.HttpRetry.BackoffPower, retryAttempt))));

    policyRegistry.Add(
        PollyPolicyName.HttpCircuitBreaker,
        HttpPolicyExtensions
            .HandleTransientHttpError()
            .CircuitBreakerAsync(
                handledEventsAllowedBeforeBreaking: policyOptions.HttpCircuitBreaker.ExceptionsAllowedBeforeBreaking,
                    durationOfBreak: policyOptions.HttpCircuitBreaker.DurationOfBreak));

    return services;

【讨论】:

【参考方案2】:

其实我并没有使用自动解压,但是实现的方法是正确注册http客户端

services.AddHttpClient<MyCustomHttpClient>()
   .ConfigureHttpMessageHandlerBuilder((c) =>
     new HttpClientHandler()
     
        AutomaticDecompression = System.Net.DecompressionMethods.GZip
     
   )
   .AddHttpMessageHandler((s) => s.GetService<MyCustomDelegatingHandler>())

【讨论】:

对我不起作用。必须使用 .ConfigureHttpMessageHandlerBuilder(builder => builder.PrimaryHandler = new HttpClientHandler() UseDefaultCredentials = true ; builder.Build(); ) 更正确地使用ConfigurePrimaryHttpMessageHandler()方法 在您的解决方案中对ConfigureHttpMessageHandlerBuilder 的第一次调用绝对没有任何作用,该方法采用Action&lt;T&gt;,而您只是返回一个立即丢弃的值:docs.microsoft.com/en-us/dotnet/api/…

以上是关于如何在 .NET Core 中使用 HttpClientHandler 和 HttpClientFactory的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ASP.Net Core 中使用 IHostedService

如何在 .Net Core ActionFilterAttribute 中使用依赖注入?

如何在 ASP.NET Core 中使用 SqlClient?

如何在 ASP.NET Core 3.1 中使用 Java?

如何在 ASP.NET Core 中使用 Route 特性

如何在 asp.net core 2.1 中使用 net.tcp 服务