C# 将自定义标头设置为 httpclient 会出现误用标头名称的错误

问题描述 投票:0回答:2

我正在尝试设置这样的自定义标题

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 的标头?不能设置自定义标题吗?

c# .net-core
2个回答
9
投票

在任何一次尝试中都使用

HttpHeaders.TryAddWithoutValidation
方法。

在内部,默认的

HttpHeaders.Add
将尝试验证您是否正在添加已知的 HTTP 标头,如果无效,则会失败。

参考 HttpHeaders


0
投票

显然这是一个SO捷径:但我首先遇到了这个,试图自己弄清楚这一点,然后最终找到下面提到的其他2个SO帖子(我猜是2021年帖子> 2013年帖子)。

不幸的是,虽然

最初接受的答案
中的.TryAddWithoutValidation似乎确实规避了像
Accept-Encoding
这样的标题上的问题,但它对像
Content-Encoding
这样的其他标题不起作用。例如,如果您在使用压缩上传数据时未指定此标头,像 Salesforce Bulk API 2.0 这样的 API 将拒绝您的请求。

原帖子中的用法与我今天的相同,因此我发布了源自 https://stackoverflow.com/a/10679340https://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 };
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.