如何为我的HttpClient PostAsync方法的第二个参数设置HttpContent?

358
public static async Task<string> GetData(string url, string data)
{
    UriBuilder fullUri = new UriBuilder(url);

    if (!string.IsNullOrEmpty(data))
        fullUri.Query = data;

    HttpClient client = new HttpClient();

    HttpResponseMessage response = await client.PostAsync(new Uri(url), /*expects HttpContent*/);

    response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    response.EnsureSuccessStatusCode();
    string responseBody = await response.Content.ReadAsStringAsync();

    return responseBody;
}
PostAsync需要另一个参数,该参数需要是HttpContent

我该如何设置HttpContent?在Windows Phone 8上没有任何可行的文档。

如果我使用GetAsync,它可以正常工作!但它需要POST并附带key="bla"和something="yay"的内容。

//编辑

非常感谢您的回答...这很好用,但还有一些不确定的地方:

    public static async Task<string> GetData(string url, string data)
    {
        data = "test=something";

        HttpClient client = new HttpClient();
        StringContent queryString = new StringContent(data);

        HttpResponseMessage response = await client.PostAsync(new Uri(url), queryString );

        //response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
        response.EnsureSuccessStatusCode();
        string responseBody = await response.Content.ReadAsStringAsync();

        return responseBody;
    }

我原以为数据 "test=something" 会被 API 端视为 "test" 的 post 数据,但显然并非如此。另外,我可能需要将整个对象/数组通过 post 数据进行发布,因此我认为使用 json 是最好的方式。您有什么想法如何将 post 数据发送出去吗?

或许可以尝试类似这样的方法:

class SomeSubData
{
    public string line1 { get; set; }
    public string line2 { get; set; }
}

class PostData
{
    public string test { get; set; }
    public SomeSubData lines { get; set; }
}

PostData data = new PostData { 
    test = "something",
    lines = new SomeSubData {
        line1 = "a line",
        line2 = "a second line"
    }
}
StringContent queryString = new StringContent(data); // But obviously that won't work

1
可能是无法找到如何使用HttpContent的重复问题。 - Liam
3个回答

225

2
我会去查一下。我想当我找到这个答案后,我会把它放在每个人都能看到的地方!这个问题已经困扰了我4天,我一直试图将一个简单的REST发送到API。 - Jimmyt1988
StringContent 运作得很好,但实际上,现在我无法将 PostData 传递到我正在调用的网站 :D。我将编辑问题以向您展示我当前拥有的内容。 - Jimmyt1988
2
“如何发布我的类的JSON表示”一个快速的答案是“使用JSON.Net将对象序列化为JSON”,但这实际上应该在一个单独的问题中提问。 - Preston Guillot

153

除了Preston的回答外,以下是标准库中可用的所有派生自HttpContent的类的完整列表:

Credit: https://pfelix.wordpress.com/2012/01/16/the-new-system-net-http-classes-message-content/

来源: https://pfelix.wordpress.com/2012/01/16/the-new-system-net-http-classes-message-content/

此外,还有一个所谓的ObjectContent,但我无法在ASP.NET Core中找到它。

当然,你也可以使用Microsoft.AspNet.WebApi.Client扩展来跳过整个HttpContent事情(现在必须要进行导入才能在ASP.NET Core中使用:https://github.com/aspnet/Home/issues/1558),然后你可以做诸如以下的事情:

var response = await client.PostAsJsonAsync("AddNewArticle", new Article
{
    Title = "New Article Title",
    Body = "New Article Body"
});

更新:对于框架版本5+,可通过以下方式实现:

using System.Net.Http.Json

不需要任何导入,你可以直接使用:

await client.PostAsJsonAsync("url", new { });

6
非常全面的答案......采用非常简洁的方法来完成看起来复杂的任务。 - Saima
1
我喜欢重复使用微软已有的内容,这样可以让代码更简洁、更清晰。 - Franva

43
    public async Task<ActionResult> Index()
    {
        apiTable table = new apiTable();
        table.Name = "Zainab Nazakat";
        table.Roll = "6655";

        string str = "";
        string str2 = "";

        HttpClient client = new HttpClient();

        string json = JsonConvert.SerializeObject(table);   //using Newtonsoft.Json

        StringContent httpContent = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

        var response = await client.PostAsync("http://YourSite.com/api/apiTables", httpContent);

        str = "" + response.Content + " : " + response.StatusCode;

        if (response.IsSuccessStatusCode)
        {       
            str2 = "Data Posted";
        }

        return View();
    }

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