标签: httpclientfactory

将IHttpClientFactory传递到.NET Standard类库

IHttpClientFactory新的ASP.NET Core 2.1中有一个非常酷的功能, https://www.hanselman.com/blog/HttpClientFactoryForTypedHttpClientInstancesInASPNETCore21.aspx

我正在尝试在ASP.NET Core 2.1 Preview-2应用程序中使用此功能,但是我需要HttpClient在.NET Standard 2.0中的类库中使用。

有一次,我执行AddHttpClientConfigureServices()Startup.cs,我怎么通过这个HttpClientFactory或命名具体HttpClient到我在.NET 2.0标准类库创建的API客户端?该客户端几乎可以处理我对第三方的所有API调用。

基本上,我只是想将特定的名称添加HttpClient到我的中thirdPartyApiClient

这是我的代码ConfigureServices()

public void ConfigureServices(IServiceCollection services)
{
    // Create HttpClient's
    services.AddHttpClient("Api123Client", client =>
    {
         client.BaseAddress = new Uri("https://api123.com/");
         client.DefaultRequestHeaders.Add("Accept", "application/json");
    });
    services.AddHttpClient("Api4567Client", client =>
    {
         client.BaseAddress = new Uri("https://api4567.com/");
         client.DefaultRequestHeaders.Add("Accept", "application/json");
    });
}
Run Code Online (Sandbox Code Playgroud)

asp.net-core .net-standard-2.0 httpclientfactory

4
推荐指数
2
解决办法
3592
查看次数

配置HttpClientFactory时出现证书错误

我需要在HttpClientFactory中添加证书.老实现HttpClient看看这个:

var cookieContainer = new CookieContainer();
var handler = new HttpClientHandler { CookieContainer = cookieContainer };

var basePath = Directory.GetCurrentDirectory();
var certificatePath = Path.Combine(basePath, certPath);
var fileExists = File.Exists(certificatePath);

if (!fileExists)
    throw new ArgumentException(certificatePath);

var certificate = new X509Certificate2(certificatePath, certPwd);
handler.ClientCertificates.Add(certificate);

using (var client = new HttpClient(handler))
{
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(accept));
    client.DefaultRequestHeaders.Add("ApiKey", apiKey);

    var body = new { UserName = username, UserPassword = password };
    var jsonBody = JsonConvert.SerializeObject(body);
    var content = new StringContent(jsonBody, Encoding.UTF8, contentType);

    var …
Run Code Online (Sandbox Code Playgroud)

c# dotnet-httpclient .net-core httpclientfactory

4
推荐指数
1
解决办法
1208
查看次数

使用 HttpClientFactory .net Core 2.1 对每个请求进行身份验证

我应该如何使用 HttpClientFactory 返回 HttpClient 的实例,其 uri 和凭据是在调用时确定的?

现有代码如下所示:

var httpClientHandler = new HttpClientHandler()
    {
        Credentials = new NetworkCredential(userName, password),
    };
HttpClient client = new HttpClient(httpClientHandler);
client.BaseAddress = new Uri(_appSetting.ServiceURI);
Run Code Online (Sandbox Code Playgroud)

c# .net-core httpclientfactory

4
推荐指数
2
解决办法
9543
查看次数

如何使用IHttpClientFactory刷新令牌

我正在使用IHttpClientFactory发送请求和使用Net Core 2.2从两个外部API接收HTTP响应。

我正在寻找一种很好的策略,以使用存储在appsettings.json中的刷新令牌来获取新的访问令牌。当当前请求返回403或401错误时,需要请求新的访问令牌。获得新的访问和刷新令牌后,需要用新值更新appsettings.json以便在后续请求中使用。

我正在使用两个客户端将请求发送到两个不同的API,但是只有其中一个使用令牌身份验证机制。

我已经实现了一些简单的方法,但是我正在寻找一种更优雅的解决方案,该解决方案可以在当前令牌到期时动态更新标头:

我已经在Startup.ConfigureServices方法中注册了IHttpClientFactory,如下所示:

services.AddHttpClient();
Run Code Online (Sandbox Code Playgroud)

注册后,我将以两种不同的方法使用它来调用两种不同的API,第一种方法是:

   public async Task<AirCallRequest> GetInformationAsync(AirCallModel model)
    {
        try
        {


            CandidateResults modelCandidateResult = null;

            var request = new HttpRequestMessage(HttpMethod.Get,
            "https://*******/v2/*****");
            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _appSettings.Value.Token);


            var clientJAAPI = _httpClientFactory.CreateClient();
            var responseclientJAAPI = await clientJAAPI.SendAsync(request);


            if (responseclientJAAPI.IsSuccessStatusCode)
            {
                modelCandidateResult = await responseclientJAAPI.Content
                   .ReadAsAsync<CandidateResults>();

                ....
            }


            if ((responseclientJAAPI .StatusCode.ToString() == "Unauthorized")
            {                    

                await RefreshAccessToken();

               //Calls recursively this method again
                return await GetInformationAsync(model);

            }

            return null;
        }
        catch (Exception e)
        {
            return null;

        }

    }
Run Code Online (Sandbox Code Playgroud)

刷新令牌方法如下所示: …

c# appsettings asp.net-core httpclientfactory

3
推荐指数
1
解决办法
916
查看次数

ConfigureServices 中的 AddHttpContextAccessor 与每个 HttpClient

在 ConfigureServices 方法中一次添加 httpContextAccessor 与为每个 HttpClient 配置添加 HttpContextAccessor 之间有什么区别。

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

    // FIRST VERSION
    services.AddHttpContextAccessor();

    // SECOND VERSION
    var myService1 = services.AddHttpClient<TestHttpClient1>(c =>
    {
        c.BaseAddress = new Uri(Configuration["TestHttpClient1"]);
    });
    myService1.Services.AddHttpContextAccessor();

    var myService2 = services.AddHttpClient<TestHttpClient2>(c =>
    {
        c.BaseAddress = new Uri(Configuration["TestHttpClient2"]);
    });
    myService2.Services.AddHttpContextAccessor();
}
Run Code Online (Sandbox Code Playgroud)

我的猜测是认为在第二个版本中,我们有两个单例,一个用于类 TestHttpClient1,另一个用于 TestHttpClient2 但我不明白为什么要这样做,因为我在生产中看到了这段代码。

c# asp.net-core httpclientfactory

3
推荐指数
1
解决办法
5185
查看次数

模拟使用 IHttpClientFactory.CreateClient 创建的 HttpClient

正如标题所暗示的,我有一些代码可以调用IHttpClientFactory.CreateClient()来创建一个 HttpClient 实例。

我在 .Net Core 3.1 中这样做

我需要嘲笑这个。根据这个问题“C# Mock IHttpclient & CreateClient”,以下应该有效......

[Test]
public void Mytest() {

    var httpClientFactory = new Mock<IHttpClientFactory>(MockBehavior.Strict);

    httpMessageHandler = new Mock<HttpMessageHandler>(MockBehavior.Strict);
    httpMessageHandler.Protected()
        // Setup the PROTECTED method to mock
        .Setup<Task<HttpResponseMessage>>(
            "SendAsync",
            ItExpr.IsAny<HttpRequestMessage>(),
            ItExpr.IsAny<CancellationToken>()
        )
        // prepare the expected response of the mocked http call
        .ReturnsAsync(new HttpResponseMessage()
        {
            StatusCode = HttpStatusCode.BadRequest,
        })
        .Verifiable();

    var httpClient = new HttpClient(httpMessageHandler.Object);

    httpClientFactory.Setup(_ => _.CreateClient())   // This fails
        .Returns(httpClient).Verifiable();

    systemUnderTest = new MyService(httpClientFactory.Object);
    var result …
Run Code Online (Sandbox Code Playgroud)

c# unit-testing httpclientfactory

3
推荐指数
1
解决办法
1572
查看次数

重新设置单例httpclient的证书(Reconfiguring IHttpclientFactory?)

使用 C#、.NET Core 3.1

httpclient通过 in添加一个单例startup.cs

services.AddHttpClient<IClientLogic, ClientLogicA>().ConfigurePrimaryHttpMessageHandler(() =>
{
   var handler = new HttpClientHandler();
   
   var cert= GetCertFromX();

   handler.ClientCertificates.Add(cert);

   return handler;
});
Run Code Online (Sandbox Code Playgroud)

但是,假设稍后在ClientLogicA课堂上,我想更改证书,我该如何执行此操作,并且更改是否会持续存在以供将来使用 httpclient 单例?

c# dependency-injection dotnet-httpclient asp.net-core httpclientfactory

3
推荐指数
1
解决办法
1595
查看次数

X 分钟后 Singleton HttpClient 是否收到新的 HttpMessageHandler

我在工厂中注册我的 HttpClient:

services.AddHttpClient<ICatalogService, CatalogService>()
    .SetHandlerLifetime(TimeSpan.FromMinutes(2));
Run Code Online (Sandbox Code Playgroud)

此 ICatalogService 通过构造函数注入到单例服务中。

2 分钟后我会在内部收到一个新的 HttpMessageHandler 还是仅在 2 分钟后将 ICatalogService 注入到非单例服务中?

基本上,当包装 HttpHandler 用作单例时,内部 HttpMessageHandler 也会过期吗?

dependency-injection httpclient asp.net-core httpclientfactory

3
推荐指数
1
解决办法
1711
查看次数

引发给定异常时无法让 Polly 重试 Http 调用

我的服务定义:

var host = new HostBuilder().ConfigureServices(services =>
{
    services
        .AddHttpClient<Downloader>()
        .AddPolicyHandler((services, request) =>
            HttpPolicyExtensions
            .HandleTransientHttpError()
            .Or<SocketException>()
            .Or<HttpRequestException>()
            .WaitAndRetryAsync(
                new[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(10) },
                onRetry: (outcome, timespan, retryAttempt, context) =>
                {
                    Console.WriteLine($"Delaying {timespan}, retrying {retryAttempt}.");
                }));

    services.AddTransient<Downloader>();

}).Build();
Run Code Online (Sandbox Code Playgroud)

实施Downloader

class Downloader
{
    private HttpClient _client;
    public Downloader(IHttpClientFactory factory)
    {
        _client = factory.CreateClient();
    }

    public Download()
    {
        await _client.GetAsync(new Uri("localhost:8800")); // A port that no application is listening
    }
}
Run Code Online (Sandbox Code Playgroud)

通过此设置,我预计会看到三次尝试查询端点,并将日志消息打印到控制台(我也尝试使用记录器但未成功,为简单起见,这里使用控制台)。

我看到的是未处理的异常消息(我只希望在重试和打印日志后看到),而不是调试消息。

未处理的异常:System.Net.Http.HttpRequestException:无法建立连接,因为目标计算机主动拒绝它。(127.0.0.1:8800) ---> System.Net.Sockets.SocketException (10061): 无法建立连接,因为目标计算机主动拒绝连接。

c# dependency-injection dotnet-httpclient polly httpclientfactory

3
推荐指数
1
解决办法
2405
查看次数

Autofac 无法解析类型化 HttpClient 的枚举

我有许多服务需要使用来自 HttpClientFactory 的类型化 HttpClient。虽然我可以解析一项服务,但我无法解析该服务的 IEnumerable。

interface IMyHttpClient
{
}

class MyHttpClient: IMyHttpClient
{
    public MyHttpClient(HttpClient client)
    {
    }
}

class Program
{
    static void Main(string[] args)
    {
        var services = new ServiceCollection();
        services.AddHttpClient()
                .AddHttpClient<IMyHttpClient, MyHttpClient>();

        var builder = new ContainerBuilder();
        // Exception goes away when remove this line
        builder.RegisterType<MyHttpClient>().As<IMyHttpClient>();
        builder.Populate(services);
        var provider = builder.Build();

        // ============== This works
        // provider.Resolve<IMyHttpClient>();

        // ============== This throws exception
        provider.Resolve<IEnumerable<IMyHttpClient>>();
    }
}
Run Code Online (Sandbox Code Playgroud)

构造函数将被调用一次,然后抛出异常:

``` DependencyResolutionException:在类型“ConsoleApp2.MyHttpClient”上找不到任何带有“Autofac.Core.Activators.Reflection.DefaultConstructorFinder”的构造函数可以使用可用的服务和参数调用:无法解析参数“System.Net.Http.HttpClient”构造函数 'Void .ctor(System.Net.Http.HttpClient)' 的客户端'。

``

问题是 AddHttpClient 添加了它自己的 IMyHttpClient 注册。但我只想使用 …

autofac httpclientfactory

2
推荐指数
1
解决办法
3305
查看次数