如何将对象传递给HttpClient.PostAsync并序列化为JSON主体?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (92)

我正在使用System.Net.Http,我在网上找到了几个例子。我设法创建了这个代码来提出POST请求:

public static string POST(string resource, string token)
{
    using (var client = new HttpClient())
    {
        client.BaseAddress = new Uri(baseUri);
        client.DefaultRequestHeaders.Add("token", token);

        var content = new FormUrlEncodedContent(new[]
        {
             new KeyValuePair<string, string>("", "")
        });

        var result = client.PostAsync("", content).Result;
        string resultContent = result.Content.ReadAsStringAsync().Result;
        return resultContent;
    }
 }

所有工作正常。但是,假设我想传递第三个参数给该POST方法,一个参数调用data。数据参数是这样一个对象:

object data = new
{
    name = "Foo",
    category = "article"
};

我怎么能做到这一点,而不创建KeyValuePair?我的PHP RestAPI等待一个JSON输入,所以FormUrlEncodedContent应该raw正确地发送JSON。但我怎么能这样做Microsoft.Net.Http呢?

提问于
用户回答回答于

直接回答你的问题是:不。PostAsync方法的签名如下:

公共任务PostAsync(Uri requestUri,HttpContent内容)

所以,虽然你可以传递objectPostAsync它的类型必须是HttpContent和你的匿名类型不符合该标准。

但是,有很多方法可以完成你想要完成的任务。首先,需要将匿名类型序列化为JSON,这是Json.NET最常用的工具。而这个代码非常简单:

var myContent = JsonConvert.SerializeObject(data);

接下来,将需要构建一个内容对象来发送这些数据,我将使用一个ByteArrayContent对象,但是如果愿意,可以使用或创建不同的类型。

var buffer = System.Text.Encoding.UTF8.GetBytes(myContent);
var byteContent = new ByteArrayContent(buffer);

接下来,要设置内容类型让API知道这是JSON。

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

然后你可以发送你的请求非常类似于你的前一个例子的表单内容:

var result = client.PostAsync("", byteContent).Result

在附注中,.Result像你在这里调用属性可能会产生一些不良的副作用,如死锁,所以你要小心这个。

用户回答回答于

需要将数据作为原始字符串传递到请求正文中,而不是FormUrlEncodedContent。一种方法是将其序列化成JSON字符串:

var json = JsonConvert.SerializeObject(data);

现在,只需将该字符串传递给post方法即可。

var stringContent = new HttpStringContent(json,
                         UnicodeEncoding.Utf8,
                         "application/json");

var client = new HttpClient();
var response = await client.PostAsync(uri, stringContent);

扫码关注云+社区