如何使用 ASP.NET Core 依赖注入将 HttpMessageHandler 注入到 HttpClient 对象中?

che*_*em7 5 c# dependency-injection httpclient

在不使用 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)
            };
Run Code Online (Sandbox Code Playgroud)

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

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

但确实,当您获得实例时,它没有 cookie 容器。

Joh*_*ica 14

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

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

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

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");
}
Run Code Online (Sandbox Code Playgroud)

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

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() }
    );
Run Code Online (Sandbox Code Playgroud)

然后你可以简单地HttpClient在你的服务中接受一个:

public class MyService
{
    public MyService(HttpClient httpClient)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @Neutrino `ConfigurePrimaryHttpMessageHandler` 的重载之一采用 `Func&lt;IServiceProvider,HttpMessageHandler&gt;`,因此您可以从容器中解析您的 `HttpMessageHandler` (因此您可以使用 `() =&gt; new ....` 来代替 `() =&gt; new ....` `sp =&gt; sp.GetRequiredService&lt;MySpecialHandler&gt;();`)。如果您不想新建自己的处理程序,可以将“DelegatingHandler”与 [`AddHttpMessageHandler`](https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection) 一起使用。 httpclientbuilderextensions.addhttpmessagehandler?view=dotnet-plat-ext-5.0) 相反。 (2认同)