协慌网

登录 贡献 社区

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

我正在尝试根据我正在调用的 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它将引发以下异常:

标头名称滥用。确保请求标头与HttpRequestMessage一起使用,响应标头与HttpResponseMessage ,以及内容标头与HttpContent对象一起使用。

如何HttpClient请求中Content-Type标头?

答案

内容类型是内容的标头,而不是请求的标头,这就是失败的原因。由 Robert Levy 建议的AddWithoutValidation可能有效,但是您也可以在创建请求内容本身时设置内容类型(请注意,代码段application/json用于 Accept 和 Content-Type 标头):

HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://example.com/");
client.DefaultRequestHeaders
      .Accept
      .Add(new MediaTypeWithQualityHeaderValue("application/json"));//ACCEPT header

HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "relativeAddress");
request.Content = new StringContent("{\"name\":\"John Doe\",\"age\":33}",
                                    Encoding.UTF8, 
                                    "application/json");//CONTENT-TYPE header

client.SendAsync(request)
      .ContinueWith(responseTask =>
      {
          Console.WriteLine("Response: {0}", responseTask.Result);
      });

对于那些没有看到约翰对卡洛斯解决方案发表评论的人...

req.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");

如果您不介意小的库依赖关系,那么 Flurl.Http可以使这个超级简单。它的PostJsonAsync方法负责序列化内容和设置content-type标头,而ReceiveJson反序列化响应。如果accept标头,则需要自己设置,但 Flurl 也提供了一种非常干净的方法:

using Flurl.Http;

var result = await "http://example.com/"
    .WithHeader("Accept", "application/json")
    .PostJsonAsync(new { ... })
    .ReceiveJson<TResult>();

Flurl 在后台使用 HttpClient 和 Json.NET,它是 PCL,因此可以在多种平台上使用。

PM> Install-Package Flurl.Http