I am trying to do a PUT request to a Web API method using HttpClient. An almost identical POST request works as expected, but the PUT request results in a 400 (Bad Request) error. I'm not sure what I'm doing wrong.
Here is my web API controller code:
public HttpResponseMessage Post(object val)
{
Debug.WriteLine(val.ToString());
return new HttpResponseMessage(HttpStatusCode.OK);
}
public HttpResponseMessage Put(int id, object val)
{
Debug.WriteLine(id.ToString(), val.ToString());
return new HttpResponseMessage(HttpStatusCode.OK);
}
And then here is the client side code that attempts to call these methods. The POST request looks like this:
var client = new HttpClient();
var content = log.ToJsonContent();
var address = new Uri(_webApiBaseAddress + "logs");
client.PostAsync(address, content).ContinueWith(requestTask =>
{
requestTask.Result.EnsureSuccessStatusCode();
});
And the PUT request that doesn't work looks like this:
var client = new HttpClient();
var content = log.ToJsonContent();
var address = new Uri(_webApiBaseAddress + "logs/" + jobId);
client.PutAsync(address, content).ContinueWith(requestTask =>
{
requestTask.Result.EnsureSuccessStatusCode();
});
As you can see, I've stripped the functionality down as bare as I can get it, and I am still getting the error with the PUT request every time.
By the way, I can make the PUT request successfully using the RestSharp client. This code successfully calls the API method:
var client = new RestClient(_webApiBaseAddress);
var request = new RestRequest("logs/{id}", Method.PUT);
request.AddUrlSegment("id", jobId.ToString());
request.AddObject(log);
client.Execute(request);
The problem with doing it this way is that any object I pass in using AddObject just ends up being a string when it gets to the controller method. If I pass in an int, I want to get an int. HttpClient does this with the POST method, so I wanted to use that, but PUT throws an error. So I'm stuck with 2 half-working solutions, which don't add up to a full solution, unfortunately. I would appreciate feedback on either pattern to get this to work.
Edit:
Because it was mentioned below, here is my .ToJsonContent()
extension method:
public static StringContent ToJsonContent(this object obj)
{
var converter = new IsoDateTimeConverter();
converter.DateTimeStyles = DateTimeStyles.AdjustToUniversal;
var json = JsonConvert.SerializeObject(obj, converter);
var content = new StringContent(json, Encoding.UTF8, "application/json");
return content;
}