我正在尝试设置这样的自定义标题
x-my-header:somecustomval
content-type:application/vnd.status+json
.
.
.
other headers
我尝试了两种方法,使用标题字典
#1
_httpClient.DefaultRequestHeaders.Clear();
foreach (var h in headers)
{
_httpClient.DefaultRequestHeaders.Add(h.Key.ToString(), h.Value.ToString());
}
#2
HttpRequestMessage req = new HttpRequestMessage();
foreach (var h in headers)
{
req.Headers.Add(h.Key.ToString(), h.Value.ToString());
}
我在这两种方法中遇到的错误是:
误用标头名称。确保请求标头与以下内容一起使用 HttpRequestMessage、带有 HttpResponseMessage 的响应标头,以及 带有 HttpContent 对象的内容标头。
如何在 C# net core 3.1 中的 HttpClient 中设置 POST 的标头?不能设置自定义标题吗?
HttpHeaders.TryAddWithoutValidation
方法。
在内部,默认的
HttpHeaders.Add
将尝试验证您是否正在添加已知的 HTTP 标头,如果无效,则会失败。
参考 HttpHeaders
显然这是一个SO捷径:但我首先遇到了这个,试图自己弄清楚这一点,然后最终找到下面提到的其他2个SO帖子(我猜是2021年帖子> 2013年帖子)。
不幸的是,虽然
最初接受的答案中的
.TryAddWithoutValidation
似乎确实规避了像Accept-Encoding
这样的标题上的问题,但它对像Content-Encoding
这样的其他标题不起作用。例如,如果您在使用压缩上传数据时未指定此标头,像 Salesforce Bulk API 2.0 这样的 API 将拒绝您的请求。
原帖子中的用法与我今天的相同,因此我发布了源自 https://stackoverflow.com/a/10679340 和 https://stackoverflow.com/a/16959464 的解决方法/901156 指示
HttpRequestMessage.Content.Headers
作为预期集合,而不是 HttpRequestMessage.Headers
。
为了将来参考,对于基于内容的标题,使用
.Headers.Add(...)
添加这两个标头的正确实现是 req.Content.Headers.Add(...)
而不是 req.Headers.Add(...)
,如下所示。
public async Task<AuthHttpResponse> AuthHttpRequest(HttpMethod method, string requestUri, byte[] data = null, string contentType = "text/csv; charset=UTF-8", bool enableCompression = true)
{
using (var req = new HttpRequestMessage(method, requestUri))
{
req.Headers.Authorization = new AuthenticationHeaderValue(DefaultAuthenticationScheme, _authToken);
if (enableCompression)
{
req.Headers.Add("Accept-Encoding", "gzip");
if (data != null)
{
req.Content = Compress(data);
req.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
req.Content.Headers.ContentEncoding.Add("gzip");
}
}
else
{
if (data != null)
{
req.Content = new ByteArrayContent(data);
req.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
}
}
var res = await _httpClient.SendAsync(req);
res.EnsureSuccessStatusCode();
string json;
// Only decompress if server acknowledged
if (res.Content.Headers.ContentEncoding.FirstOrDefault() == "gzip")
{
var buffer = await res.Content.ReadAsByteArrayAsync();
using (var stream = new MemoryStream(buffer))
json = await Decompress(stream);
}
else
{
json = await res.Content.ReadAsStringAsync();
}
return new AuthHttpResponse { Content = json, Response = res };
}
}