我试图设置一个HttpClient对象的Content-Type头作为我调用的API所要求的。
我试着像下面这样设置内容类型:
using (var httpClient = new HttpClient())
{
httpClient.BaseAddress = new Uri("http://example.com/");
httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
httpClient.DefaultRequestHeaders.Add("Content-Type", "application/json");
// ...
}
它允许我添加Accept头,但当我尝试添加Content-Type时,它会抛出以下异常:
误用头名称。确保请求头与一起使用
HttpRequestMessage,带有HttpResponseMessage的响应头,以及
内容头与HttpContent对象。
如何在HttpClient请求中设置内容类型报头?
诀窍在于你可以设置各种标题,比如:
HttpRequestMessage request = new HttpRequestMessage();
request.Headers.Add("Accept-Language", "en"); //works OK
但不是任何标题。例如:
request.Headers.Add("Content-Type", "application/json");//wrong
将引发运行时异常“误用头名”。这似乎是可行的:
request.Headers.Add(
HttpRequestHeader.ContentType.ToString(), //useless
"application/json"
);
但是这样会产生一个名为ContentType的无用头,没有连字符。标头名称不区分大小写,但对连字符非常敏感。
解决方案是在将body添加到http请求的Content部分时声明body的编码和类型:
string Body = "...";
request.Content =
new StringContent(Body, Encoding.UTF8, "application/json");
只有这样,适用的http头才会自动添加到请求中:
Content-Type: application/json; charset=utf-8
在一台没有代理服务器的机器上,使用Fiddler很难发现这一点。Visual Studio曾经有一个网络工具,你可以在其中检查所有的头文件,但只能在版本2015,而不是在更新的版本2017或2022。如果使用调试器检查请求。头文件,你不会发现由StringContent()自动添加的头文件。
我用RestSharp得到了答案:
private async Task<string> GetAccessTokenAsync()
{
var client = new RestClient(_baseURL);
var request = new RestRequest("auth/v1/login", Method.POST, DataFormat.Json);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("x-api-key", _apiKey);
request.AddHeader("Accept-Language", "br");
request.AddHeader("x-client-tenant", "1");
...
}
这对我很管用。