由于 Microsoft建议创建HttpClient
一次并在程序的整个生命周期中重复使用,我想知道如何更新DefaultRequestHeaders
,例如,令牌已过期并且需要刷新。
DefaultRequestHeaders
更多的是不是线程安全的(据我所知),并且在那里定义的标头列表由所有潜在的待处理请求共享。带有新标记Clear()
的列表和标题似乎不是明智的做法。Add()
更新
更准确地说,我不想/不需要为每个请求更改请求标头。仅当我获得 HTTP 401 状态代码时。
由于 Microsoft建议创建HttpClient
一次并在程序的整个生命周期中重复使用,我想知道如何更新DefaultRequestHeaders
,例如,令牌已过期并且需要刷新。
DefaultRequestHeaders
更多的是不是线程安全的(据我所知),并且在那里定义的标头列表由所有潜在的待处理请求共享。带有新标记Clear()
的列表和标题似乎不是明智的做法。Add()
更准确地说,我不想/不需要为每个请求更改请求标头。仅当我获得 HTTP 401 状态代码时。
当您在 DI 容器注册阶段注册 IHttpClient 或使用其他模式(如工厂或单例)返回带有自定义消息处理程序的 IHttpClient 实例时,将消息处理程序与您的 HttpClient 连接起来。检查出站呼叫并添加必要的标头。
https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/httpclient-message-handlers
示例标头消息处理程序
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());
线程问题
关于线程问题或并发性,方法HttpRequestMessage
上的参数SendAsync
将是每个请求。如果您将标头添加到request.Headers
集合中,您将仅更新该请求实例的标头(即,不是全局的)
request.Headers
或者在实例上使用 Authorization 属性:
request.Headers.Authorization = new AuthenticationHeaderValue("bearer", bearerToken);
请参阅下面的 MSDN 链接
https://msdn.microsoft.com/en-us/library/system.net.http.httprequestmessage
如果您DefaultRequestHeaders
在 HttpClient 的静态、共享、单例、Lifestyle.Singleton 等实例上使用,那么您将遇到线程问题并且需要适当的同步来更新DefaultRequestHeaders
集合。