IHttpClientFactory 并更改基础 HttpClient.BaseAddress

Posted

技术标签:

【中文标题】IHttpClientFactory 并更改基础 HttpClient.BaseAddress【英文标题】:IHttpClientFactory and changing the base HttpClient.BaseAddress 【发布时间】:2020-06-01 19:34:47 【问题描述】:

IHttpClientFactory 和更改 HttpClient.BaseAddress 的最佳做法是什么?

在创建我的依赖注入时,我这样做:

services.AddHttpClient("MyApp", c =>
    
        c.BaseAddress = new Uri("https://myurl/");
        c.DefaultRequestHeaders.Add("Accept", "application/json");
    ).ConfigurePrimaryHttpMessageHandler(handler => new HttpClientHandler()
     AutomaticDecompression = DecompressionMethods.GZip );

然后当我需要一个 HttpClient 这样做时:

var client = clientFactory.CreateClient("MyApp");

这很好用,但有时在运行时需要更改 BaseAddress。在运行期间,我无法在注入后更改 BaseAddress。现在我可以完全忽略 BaseAddress 并在 API 调用中发送整个地址,但是,我不知道这是否是正确的做法。像这样的:

await using var stream = await client.GetStreamAsync($"addresss/api");
using var streamReader = new StreamReader(stream);
using var textReader = new JsonTextReader(streamReader);
var serializer = new JsonSerializer();
data = serializer.Deserialize<List<T>>(textReader);

【问题讨论】:

几个想法,我可以发誓注入后基地址是可配置的,但如果不是,您可能希望使用两个客户端并将CreateClient 移动到更靠近您需要特定基地址的位置并使用你在那里的第二个客户。只是一些想法 @JSteward 当我从直接 HttpClient 切换到 IHttpClientFactory 时,我无法更改 BaseAddress。不需要有两个客户端,基本上,该应用程序允许在运行时更改配置。 【参考方案1】:

在运行期间,有时 BaseAddress 需要更改。在运行期间,我无法在注入后更改 BaseAddress。

BaseAddress 可以更改,直到发送第一个请求。此时,它被锁定,无法再次更改。 HttpClient 工厂模式假定每个注入的客户端只有一个 BaseAddress(可能未设置)。

现在我可以完全忽略 BaseAddress,只在 API 调用中发送整个地址,但是,我不知道这是否是正确的做法。

您的选择是:

    定义多个客户端,每个BaseAddress 一个。如果您有几个知名主机,这是正常的方法。 定义单个客户端,不要使用BaseAddress,在每次调用中传递整个url。这是完全允许的。 定义您自己的工厂类型,使用IHttpClientFactory 传递HttpClient 实例,其中每个实例都可以指定自己的BaseAddress。如果您有一些代码需要 BaseAddress(例如 Refit),但需要与动态主机一起使用,我只会使用这种更复杂的方法。

【讨论】:

那么关于第二点,像 httpClientFactory.Create() 这样的东西会起作用吗?甚至只使用 DI: constructor(HttpClient client)? @Ssss:其中任何一个都可以获取HttpClient 实例。 选项 2 对我来说似乎是最好的,但是我可以找到任何关于这个问题的文档。我不断收到异常:InvalidOperationException: BaseAddress 必须在 HttpClient 实例上设置。 @Xserge:一些第三方库(即Refit)需要一个BaseAddress

以上是关于IHttpClientFactory 并更改基础 HttpClient.BaseAddress的主要内容,如果未能解决你的问题,请参考以下文章

如何在ASP.NET Core 中使用IHttpClientFactory

单元测试 | 如何Mock IHttpClientFactory

转.NET Core开发日志——IHttpClientFactory

通过 IHttpClientFactory 忽略 SSL 连接错误

Net Core 3.1 IHttpClientFactory/HttpClient 第一次请求慢

如何为每个 url 使用 Polly 和 IHttpClientFactory