我试图设置一个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请求中设置内容类型报头?


当前回答

你需要这样做:

    HttpContent httpContent = new StringContent(@"{ the json string }");
    httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));                
    HttpResponseMessage message = client.PostAsync(@"{url}", httpContent).Result;

其他回答

调用AddWithoutValidation而不是Add(参见MSDN链接)。

或者,我猜您正在使用的API实际上只需要POST或PUT请求(而不是普通的GET请求)。在这种情况下,当您调用HttpClient时。然后传入一个HttpContent,在HttpContent对象的Headers属性上设置这个。

为那些受困于字符集的人准备的

我有一个非常特殊的情况,服务提供商不接受字符集,他们拒绝改变子结构来允许它…… 不幸的是,HttpClient通过StringContent自动设置报头,不管你传递的是null还是Encoding。UTF8,它总是会设置字符集…

今天我在改变子系统的边缘;从HttpClient转向其他东西,我想到了一些东西…,为什么不用反射来清空“字符集”呢?... 在我尝试之前,我想到了一种方法,“也许我可以在初始化后改变它”,这是有效的。

下面是如何设置“application/json”头没有“;charset = utf - 8”。

var jsonRequest = JsonSerializeObject(req, options); // Custom function that parse object to string
var stringContent = new StringContent(jsonRequest, Encoding.UTF8, "application/json");
stringContent.Headers.ContentType.CharSet = null;
return stringContent;

注意:下面的空值无效,加";charset = utf - 8”

return new StringContent(jsonRequest, null, "application/json");

EDIT

@DesertFoxAZ建议也可以使用下面的代码,工作良好。(没有自己测试,如果它的工作率,并在评论中赞扬他)

stringContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");

Api返回

"不支持的媒体类型","状态":415

添加ContentType到jsonstring做了魔法,这是我的脚本工作100%到今天为止

    using (var client = new HttpClient())
            {
                   var endpoint = "api/endpoint;
                    var userName = "xxxxxxxxxx";
                    var passwd = "xxxxxxxxxx";
                    var content = new StringContent(jsonString, Encoding.UTF8, "application/json");

                    var authToken = Encoding.ASCII.GetBytes($"{userName}:{passwd}");

                client.BaseAddress = new Uri("https://example.com/");

                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(authToken));
            
                HttpResponseMessage response = await client.PostAsync(endpoint, content);

                if (response.IsSuccessStatusCode)
                {
                    // Get the URI of the created resource.
                    Uri returnUrl = response.Headers.Location;
                    Console.WriteLine(returnUrl);
                }
                string responseBody = await response.Content.ReadAsStringAsync();
                return responseBody;
        }

内容类型是内容的头,而不是请求的头,这就是失败的原因。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);
      });

我也有类似的问题。 所以我发现Software PostMan可以在点击左上角的“code”按钮时生成代码。从中我们可以看到在“引擎盖下”发生了什么,HTTP调用是用许多代码语言生成的;curl命令,c# RestShart, java, nodeJs,…

这对我帮助很大,而不是使用。net基础HttpClient,我最终使用RestSharp nuget包。

希望能帮助到其他人!