HttpClient 标头与 HttpRequestMessage 标头

Posted

技术标签:

【中文标题】HttpClient 标头与 HttpRequestMessage 标头【英文标题】:HttpClient Headers vs HttpRequestMessage Headers 【发布时间】:2015-10-03 13:29:58 【问题描述】:

我们什么时候应该在 HttpRequestMessage 对象中使用标头而不是 HttpClient 中的标头??

我们需要添加授权(总是在变化)和一些自定义标题(总是在变化)

问题

    首选方法是什么?

    我应该添加常见的吗 HttpClient 和请求的标头(所有请求都相同) 基于 HttpRequestMessage 对象的标头??

       //HttpRequestMessage Code
        HttpRequestMessage reqmsg =new HttpRequestMessage();
        reqmsg.Headers.Authorization =new AuthenticationHeaderValue("some scheme");
        reqmsg.Headers.Add("name","value");
    
        //HttpClient Code
        HttpClient client =new HttpClient();
        client.DefaultRequestHeaders.Authorization =new AuthenticationHeaderValue("some scheme");
        client.DefaultRequestHeaders.Add("name", "value");
    

【问题讨论】:

也许是个挑剔,但目前的想法似乎是将 HttpClient 实例化为单例,而不是作为短期对象(在这种情况下,不要忘记 Dispose/use 'using') . @MaxBarraclough 现在的普遍共识似乎是将 HttpClient 包装在 using 块中,因为它会泄漏连接而不仅仅是回收HttpClient。请查看这些 SO 问题中的一些 cmets:Question-1 和 Question-2 @AnthonyWalsh 这篇文章同意你的观点:似乎我的第一个建议很好,但我的第二个建议不是:aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong 【参考方案1】:
    首选方法是什么?我应该向 HttpClient 添加通用标头(所有请求都相同) 和 HttpRequestMessage 对象的基于请求的标头??

您的问题会自动回答。

DefaultRequestHeaders 是任何请求的一部分,这是一个优点,因为您将能够避免重复自己一遍又一遍地添加一些标头。另一方面,HttpRequestMessage.Headers 将只是该请求的一部分。

你应该在什么时候使用一个而不是另一个?我将使用两个示例:

我需要发送一个 OAuth 不记名令牌作为每个请求的一部分,所以我在 HttpClient.DefaultRequestHeaders 中设置了 Authorization 标头,如果我需要刷新令牌,我只需要在那里再次设置它.

我需要根据某些条件发送一个序列化为 JSON 或 XML 的实体。也就是说,我将在每个请求的基础上设置 Content-type 标头。

【讨论】:

"如果我需要刷新令牌,我只需要在那里重新设置。"我不认为更改 DefaultRequestHeaders 是线程安全的...... @Aldracor 你是正确的,因为 DefaultRequestHeaders 不是线程安全的。推荐的做法是为整个应用程序使用 HttpClient 的静态实例。永远不要使用 DefaultRequestHeaders 或 BaseAddress,始终使用 HttpRequestMessage。

以上是关于HttpClient 标头与 HttpRequestMessage 标头的主要内容,如果未能解决你的问题,请参考以下文章

c# httpclient 授权标头对我不起作用?

设置HttpClient的授权标头

带有标头和正文的 HTTPClient 发布请求

更新添加为 HttpClient 的 DefaultRequestHeaders 的自定义标头值

如何为 HttpClient 请求设置 Content-Type 标头?

使用 HttpClient 发送 MultipartFormDataContent 时设置 ContentType 标头