【问题标题】:How do you inject the HttpMessageHandler into the HttpClient object using ASP.NET Core dependency injection?如何使用 ASP.NET Core 依赖注入将 HttpMessageHandler 注入到 HttpClient 对象中?
【发布时间】:2019-07-25 01:31:03
【问题描述】:

不使用 ASP.NET Core 的 DI,您可以使用其构造函数将包含 cookie 容器的 ClientHandler 放入 HttpClient 对象中,类似于以下内容:

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

        var client = new HttpClient(handler)
            {
                BaseAddress = new Uri(uri),
                Timeout = TimeSpan.FromMinutes(5)
            };

但是当你尝试使用 DI 时,你没有机会调用 HttpClient 的构造函数并将处理程序传入。我尝试了下一行代码:

        services.AddHttpClient<HttpClient>(client =>
            {
                client.BaseAddress = new Uri(uri);
                client.Timeout = TimeSpan.FromSeconds(5);
            });

但实际上,当您获取实例时,它没有 cookie 容器。

【问题讨论】:

  • OP 我更新了我的答案,因为有(可能)更好的方法。

标签: c# dependency-injection httpclient


【解决方案1】:

您可以通过添加命名客户端(具有其他配置选项)来实现此目的。我们将简单地创建一个带有 cookie 容器的新 HttpClientHandler

services.AddHttpClient("myServiceClient")
    .ConfigureHttpClient(client =>
    {
        client.BaseAddress = new Uri(uri);
        client.Timeout = TimeSpan.FromSeconds(5);
    })
    .ConfigurePrimaryHttpMessageHandler(
        () => new HttpClientHandler() { CookieContainer = new CookieContainer() }
    );

然后你可以像这样解析客户端:

public class MyService(IHttpClientFactory clientFactory)
{
    // "myServiceClient" should probably be replaced in both places with a 
    // constant (const) string value to avoid magic strings
    var httpClient = clientFactory.CreateClient("myServiceClient");
}

还可以通过向AddHttpClient 提供通用参数来将HttpClient 绑定到服务:

services.AddHttpClient<MyService>("myServiceClient") // or services.AddHttpClient<MyServiceInterface, MyServiceImplementation>("myServiceClient")
    .ConfigureHttpClient(client =>
    {
        client.BaseAddress = new Uri(uri);
        client.Timeout = TimeSpan.FromSeconds(5);
    })
    .ConfigurePrimaryHttpMessageHandler(
        () => new HttpClientHandler() { CookieContainer = new CookieContainer() }
    );

然后您可以在您的服务中简单地接受HttpClient

public class MyService
{
    public MyService(HttpClient httpClient)
    {
    }
}

【讨论】:

  • 这很好,除了你必须“新”HttpClientHandler 自己的依赖项。我有一个 HttpClientHandler 来操纵转发请求的身份验证,因此我需要将 TokenService 和 IHttpContextAccessor 注入其中。我该怎么做?
  • @Neutrino ConfigurePrimaryHttpMessageHandler 的重载之一采用Func&lt;IServiceProvider,HttpMessageHandler&gt;,因此您可以从容器中解析您的HttpMessageHandler(因此您可以使用sp =&gt; sp.GetRequiredService&lt;MySpecialHandler&gt;(); 而不是() =&gt; new ....)。如果您不想新建自己的处理程序,可以使用 DelegatingHandlerAddHttpMessageHandler
  • 完美。我不知道存在过载,但效果很好。谢谢约翰。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-02-24
  • 2016-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-16
  • 2019-02-22
相关资源
最近更新 更多