366
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;
}

The PostAsync takes another parameter that needs to be HttpContent.

How do I set up an HttpContent? There Is no documentation anywhere that works for Windows Phone 8.

If I do GetAsync, it works great! but it needs to be POST with the content of key="bla", something="yay"

//EDIT

Thanks so much for the answer... This works well, but still a few unsures here:

    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;
    }

The data "test=something" I assumed would pick up on the api side as post data "test", evidently it does not. On another matter, I may need to post entire objects/arrays through post data, so I assume json will be best to do so. Any thoughts on how I get post data through?

Perhaps something like:

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

3 Answers 3

231

This is answered in some of the answers to Can't find how to use HttpContent as well as in this blog post.

In summary, you can't directly set up an instance of HttpContent because it is an abstract class. You need to use one the classes derived from it depending on your need. Most likely StringContent, which lets you set the string value of the response, the encoding, and the media type in the constructor. See: http://msdn.microsoft.com/en-us/library/system.net.http.stringcontent.aspx

3
  • 2
    I'll check this out. I think when I find this out, i'm going to have to put this somewhere where everyone can see it! This has had me going for 4 days now, trying to get a simple REST to an API.
    – Jimmyt1988
    Commented Sep 24, 2013 at 9:28
  • The StringContent worked great, but actually, can't get the PostData to get through to the site i'm calling now :D. I'll edit question to show you what I now currently have
    – Jimmyt1988
    Commented Sep 24, 2013 at 22:40
  • 2
    A quick answer to "how do i post a JSON reprsentation of my class" is "serialize the object to JSON, probably with JSON.Net", but that really belongs in a separate question. Commented Sep 24, 2013 at 23:05
155

To add to Preston's answer, here's the complete list of the HttpContent derived classes available in the standard library:

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

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

There's also a supposed ObjectContent but I was unable to find it in ASP.NET Core.

Of course, you could skip the whole HttpContent thing all together with Microsoft.AspNet.WebApi.Client extensions (you'll have to do an import to get it to work in ASP.NET Core for now: https://github.com/aspnet/Home/issues/1558) and then you can do things like:

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

Update: For framework versions 5+, via:

using System.Net.Http.Json

Without any imports, you can just use use:

await client.PostAsJsonAsync("url", new { });
2
  • 6
    Most comprehensive answer.. very neat and clean way to achieve apparently complicated task.
    – Saima
    Commented Jun 20, 2019 at 9:58
  • 1
    I like the re-use of what Microsoft already has, plus it makes the code so much less and clean.
    – Franva
    Commented Aug 19, 2020 at 6:43
46
    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 = "Status : " + response.Content + " : " + response.StatusCode;

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

        return View();
    }

Not the answer you're looking for? Browse other questions tagged or ask your own question.