indot_brad indot_brad - 3 months ago 67
C# Question

How to use System.Net.HttpClient to post a complex type?

I have a custom complex type that I want to work with using Web API.

public class Widget
{
public int ID { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}


And here is my web API controller method. I want to post this object like so:

public class TestController : ApiController
{
// POST /api/test
public HttpResponseMessage<Widget> Post(Widget widget)
{
widget.ID = 1; // hardcoded for now. TODO: Save to db and return newly created ID

var response = new HttpResponseMessage<Widget>(widget, HttpStatusCode.Created);
response.Headers.Location = new Uri(Request.RequestUri, "/api/test/" + widget.ID.ToString());
return response;
}
}


And now I'd like to use System.Net.HttpClient to make the call to the method. However, I'm unsure of what type of object to pass into the PostAsync method, and how to construct it. Here is some sample client code.

var client = new HttpClient();
HttpContent content = new StringContent("???"); // how do I construct the Widget to post?
client.PostAsync("http://localhost:44268/api/test", content).ContinueWith(
(postTask) =>
{
postTask.Result.EnsureSuccessStatusCode();
});


How do I create the HttpContent object in a way that web API will understand it?

Answer

The generic HttpRequestMessage<T> has been removed. This :

new HttpRequestMessage<Widget>(widget)

will no longer work.

Instead, from this post, the ASP.NET team has included some new calls to support this functionality:

HttpClient.PostAsJsonAsync<T>(T value) sends “application/json”
HttpClient.PostAsXmlAsync<T>(T value) sends “application/xml”

So, the new code (from dunston) becomes:

Widget widget = new Widget()
widget.Name = "test"
widget.Price = 1;

HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:44268");
client.PostAsJsonAsync("api/test", widget)
    .ContinueWith((postTask) => postTask.Result.EnsureSuccessStatusCode() );