gpt4 book ai didi

c# - 当每个请求都需要新的授权 header 时,在 Web 应用程序中重用 HttpClient

转载 作者:太空宇宙 更新时间:2023-11-03 15:15:04 24 4
gpt4 key购买 nike

我已经阅读了大量有关如何尽可能重用 HttpClient 实例,甚至可能在整个应用程序生命周期中重用的内容。为了完整起见,以下是我的陈述所依据的一些资源:

我有几个问题:

  1. 如何在 ASP.NET MVC 中创建 HttpClient 的应用程序范围实例以在所有请求之间共享?让我们假设图片中没有 IoC 容器,所以我不能只使用 container-name-here 将它绑定(bind)在 Singleton 范围内然后就此结束。我将如何“手动”?
  2. 此外,我正在与之交互的网络服务需要每个请求的新授权 token ,因此即使想出一种方法来执行上面的#1,我如何为每个请求提供一个新的授权 header ,以便它不会与潜在的多个并发请求(来自不同用户等等)发生冲突?我的理解是,当涉及到 GetAsync 和其他方法时,HttpClient 本身是相当线程安全的,但设置 DefaultAuthorizationHeaders 对我来说似乎不是线程安全的,是吗?
  3. 如何让它保持单元可测试性?

到目前为止,这是我正在进行的代码的样子(为简洁起见,这里采用了某种简化的形式):

public class MyHttpClientWrapper : IDisposable
{
private readonly HttpClient _httpClient;
private readonly TokenManager _tokenManager;

public HttpServiceClient(HttpClient httpClient, TokenManager tokenManager)
{
_httpClient = httpClient;
_tokenManager = tokenManager;

_httpClient.BaseAddress = new Uri("https://someapp/api/");
_httpClient.DefaultRequestHeaders.Accept.Add(new
MediaTypeWithQualityHeaderValue("application/json"));
}

public string GetDataByQuery(string query)
{
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"amx", _tokenManager.GetNewAuthorizationCode());

var response = _httpClient.GetAsync(query).Result;
return response.Content.ReadAsStringAsync().Result;
}

public void Dispose()
{
HttpClient?.Dispose();
}
}

旁注:我在这里使用依赖注入(inject),但不一定是 IoC 容器(出于与本讨论无关的原因)。

最佳答案

在网上进一步阅读之后,我想到了这个:

public class MyHttpClientWrapper
{
private static readonly HttpClient _httpClient;
private readonly TokenManager _tokenManager;

static MyHttpClientWrapper()
{
// Initialize the static http client:
_httpClient = new HttpClient();
_httpClient.BaseAddress = new Uri("https://someapp/api/");
_httpClient.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
}

public HttpServiceClient(TokenManager tokenManager)
{
_tokenManager = tokenManager;
}

public string GetDataByQuery(string query)
{
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"amx", _tokenManager.GetNewAuthorizationCode());

var response = _httpClient.GetAsync(query).Result;
return response.Content.ReadAsStringAsync().Result;
}

}

唯一的问题是,它不可单元测试。我无法用假的替换 http 客户端。我可以将 _httpClient 封装在一个属性中并使其成为非只读的。这样,httpclient 就可以通过属性 setter 从单元测试中被覆盖。我不确定我是否喜欢这个解决方案。

另一个想法是通过属性对静态 _httpClient 进行延迟初始化,但我不确定这是否更好。

对这两个想法有什么想法吗?还有其他想法吗?

关于c# - 当每个请求都需要新的授权 header 时,在 Web 应用程序中重用 HttpClient,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39297600/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com