我正在尝试按照我调用的API的要求设置 HttpClient
对象的 Content-Type
标头 .
我尝试设置 Content-Type
如下:
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
时,它会抛出以下异常:
未使用的 Headers 名称 . 确保请求标头与HttpRequestMessage一起使用,响应标头与HttpResponseMessage一起使用,内容标头与HttpContent对象一起使用 .
如何在 HttpClient
请求中设置 Content-Type
标头?
9 回答
关于.NET Core的一些额外信息(在阅读erdomke关于设置私有字段以在没有内容的请求上提供内容类型的帖子之后)...
调试我的代码后,我无法通过反射看到私有字段设置 - 所以我想我会尝试重新创建问题 .
我使用.Net 4.6尝试了以下代码:
并且,正如预期的那样,我得到了内容
"Cannot send a content-body with this verb-type."
的聚合异常但是,如果我使用.NET Core(1.1)做同样的事情 - I don't get an exception. 我的服务器应用程序非常高兴地回答了我的请求,并且内容类型已被选中 .
我对此感到惊喜,我希望它对某人有所帮助!
内容类型是内容的 Headers ,而不是请求的 Headers ,这就是失败的原因 . 根据Robert Levy的建议,
AddWithoutValidation
也可以,但您也可以在创建请求内容时设置内容类型(请注意,代码片段在两个位置添加了"application/json" - 用于Accept和Content-Type标头):try to use TryAddWithoutValidation
.Net试图强迫您遵守某些标准,即只能在具有内容的请求(例如
POST
,PUT
等)上指定Content-Type
标头 . 因此,正如其他人所指出的那样,设置Content-Type
标头的首选方法是通过HttpContent.Headers.ContentType属性 .话虽如此,某些API(例如LiquidFiles Api,截至2016-12-19)需要为
GET
请求设置Content-Type
标头 . .Net不允许在请求本身上设置此标头 - 即使使用TryAddWithoutValidation
. 此外,您不能为请求指定Content
- 即使它是零长度 . 我似乎唯一能解决这个问题的方法就是采取反思 . 代码(如果其他人需要它)是Edit:
如评论中所述,该字段在dll的不同版本中具有不同的名称 . 在source code on GitHub中,该字段当前名为
s_invalidHeaders
. 根据@David Thompson的建议,该示例已经过修改以解释此问题 .对于那些没有看到约翰斯评论卡洛斯解决方案的人......
好吧,它不是HTTPClient但是如果你可以使用它,WebClient很容易:
这就是你需要的一切 .
使用Newtonsoft.Json,如果你需要一个内容作为json字符串 .
调用
AddWithoutValidation
而不是Add
(参见this MSDN link) .或者,我猜你正在使用的API实际上只需要POST或PUT请求(不是普通的GET请求) . 在这种情况下,当您调用
HttpClient.PostAsync
并传入HttpContent
时,请在该HttpContent
对象的Headers
属性上设置此项 .如果你不介意一个小的库依赖,Flurl.Http [披露:我是作者]使这个超级简单 . 它的
PostJsonAsync
方法负责序列化内容和设置content-type
标头,ReceiveJson
反序列化响应 . 如果需要accept
标头,您需要自己设置,但Flurl也提供了一种非常干净的方法:Flurl使用HttpClient和Json.NET,它是一个PCL,因此它可以在各种平台上运行 .