自微软 recommends HttpClient
创建一次并在程序的整个生命周期中重复使用,我想知道如何更新 DefaultRequestHeaders
例如, token 已过期并需要刷新。
DefaultRequestHeaders
不仅仅是线程安全的(据我所知),而且那里定义的 header 列表由所有潜在的待处理请求共享。 Clear()
列表和 Add()
带有新 token 的 header ,似乎不是明智之举。
更新
更准确地说,我不想/不需要更改每个请求的请求 header 。仅当我收到 HTTP 401 状态代码时。
最佳答案
当您在 DI 容器注册表阶段注册 IHttpClient 时,将消息处理程序与 HttpClient 连接起来,或者使用其他模式(例如工厂或单例)来返回带有自定义消息处理程序的 IHttpClient 实例。检查出站调用并添加必要的 header 。
https://learn.microsoft.com/en-us/aspnet/web-api/overview/advanced/httpclient-message-handlers
示例 header 消息处理程序
class MessageHandler1 : DelegatingHandler
{
private int _count = 0;
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
System.Threading.Interlocked.Increment(ref _count);
request.Headers.Add("X-Custom-Header", _count.ToString());
return base.SendAsync(request, cancellationToken);
}
}
示例记录器消息处理程序:
class LoggingHandler : DelegatingHandler
{
StreamWriter _writer;
public LoggingHandler(Stream stream)
{
_writer = new StreamWriter(stream);
}
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
var response = await base.SendAsync(request, cancellationToken);
if (!response.IsSuccessStatusCode)
{
_writer.WriteLine("{0}\t{1}\t{2}", request.RequestUri,
(int)response.StatusCode, response.Headers.Date);
}
return response;
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
_writer.Dispose();
}
base.Dispose(disposing);
}
}
将其添加到管道
HttpClient client = HttpClientFactory.Create(new Handler1(), new Handler2(), new Handler3());
线程问题
关于线程问题或并发性,SendAsync
方法上的 HttpRequestMessage
参数将针对每个请求。如果将 header 添加到 request.Headers
集合中,您将仅更新该请求实例的 header (即不是全局的)
或者使用 request.Headers
实例上的 Authorization 属性:
request.Headers.Authorization = new AuthenticationHeaderValue("bearer", bearerToken);
请参阅下面的 MSDN 链接
https://msdn.microsoft.com/en-us/library/system.net.http.httprequestmessage
如果您在 HttpClient 的静态、共享、单例、Lifestyle.Singleton 等实例上使用 DefaultRequestHeaders
,那么您将遇到线程问题,并且需要适当的同步来更新 DefaultRequestHeaders
集合。
关于C# HttpClient刷新 token 策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49953560/