如何使用C# HttpClient正确执行JSON对象的HTTP Post请求?

6

我有一个非常简单的C# Http Client控制台应用程序,需要将一个json对象以HTTP POST方式发送到WebAPI v2。 目前,我的应用程序可以使用FormUrlEncodedContent进行POST:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;
using System.Net.Http.Headers;
using Newtonsoft.Json;
using System.Net.Http.Formatting;


namespace Client1
{
    class Program
    {
        class Product
        {
            public string Name { get; set; }
            public double Price { get; set; }
            public string Category { get; set; }
        }
        static void Main(string[] args)
        {
             RunAsync().Wait();
        }
        static async Task RunAsync()
        {
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri("http://localhost:8888/");
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                var content = new FormUrlEncodedContent(new[] 
                        {
                            new KeyValuePair<string, string>("Category", "value-1"),
                            new KeyValuePair<string, string>("Name", "value-2")                           
                       });

                var result = client.PostAsync("Incident", content).Result;      
                var r = result;     
            }
        }
    }
}

然而,当我尝试在POST请求中使用JSON时,出现了错误415 - 不支持的媒体类型:

class Product
{
    public string Name { get; set; }
    public double Price { get; set; }
    public string Category { get; set; }
}

var gizmo = new Product() { Name = "Gizmo", Price = 100, Category = "Widget" };
var  response = await client.PostAsJsonAsync("api/products", gizmo);

执行显式JSON序列化对我来说并没有改变结果:
string json = JsonConvert.SerializeObject(product);
var  response = await client.PostAsJsonAsync("api/products", json);

如何正确处理并能够发送JSON POST请求?


1
你是否拥有服务器实现?415 - 不支持的媒体类型是一个服务器端错误,它表示不支持JSON,因此与你的客户端代码无关。 - Jacob
是的,我的服务器端是一个OData控制器:[HttpPost] public void Post([FromBody] Product value) { var req = Request; var p = value; } - Eugene Goldberg
1
是的,但你的服务器项目配置接受和返回JSON了吗?看一下在请求中添加头部来表示你正在发送JSON。 - krillgar
只是确认一下,因为我在你遇到问题的代码中没有看到它,你是否仍然像在代码片段中那样设置了媒体类型?client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - Always Learning
1
这个客户端代码仍然给我返回415错误: var gizmo = new Product() { Name = "Gizmo", Price = 100, Category = "Widget" }; var json = JsonConvert.SerializeObject(gizmo); var response = await client.PostAsJsonAsync("/Incident", new StringContent(json, Encoding.UTF32, "application/json")); - Eugene Goldberg
无论你如何更改客户端代码,问题都在服务器上。 - Jacob
2个回答

3

如果你希望将它发送为 FormUrlEncodedContent,那么使用 MediaTypeWithQualityHeaderValue("application/json") 是错误的。这会将请求内容类型设置为json。相反,应该使用“application/x-www-form-urlencoded”或者根本不设置MediaTypeWithQualityHeaderValue。


3
当我发布 FormUrlEncodedContent 时,这是我使用的代码范围。
        HttpContent content = new FormUrlEncodedContent(new Dictionary<string, string>
        {
            {"grant_type", "password"},
            {"client_id", _clientId},
            {"client_secret", _clientSecret},
            {"username", _userName},
            {"password", _password}
        }
            );

            var message =
                await httpClient.PostAsync(_authorizationUrl, content);

_authorizationUrl 是一个绝对地址(absolute url)。

我没有设置这些属性中的任何一个。

           client.BaseAddress = new Uri("http://localhost:8888/");
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

像你这样。

没错。这就是我在下面回答中所说的。但不知道为什么有人对此进行了负评。 - Developer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接