How to correctly use PostAsync and PutAsync?http://forums.asp.net/t/1773007.aspx/1?How+to+correctly+use+PostAsync+and+PutAsync+Mon, 27 Feb 2012 08:43:09 -050017730074847334http://forums.asp.net/p/1773007/4847334.aspx/1?How+to+correctly+use+PostAsync+and+PutAsync+How to correctly use PostAsync and PutAsync? <p>Hi Everyone,</p> <p>&nbsp; I'm trying to setup an API for my BLL and I got GET and DELETE actions working fine. &nbsp;Now I'm trying to submit data back to the API with PUT but I can't get it to work. &nbsp;Specifically, I'm using HttpClient as the client to talk to Web API.</p> <p>Here is the code I'm using which just hangs:</p> <pre><span>public</span>&nbsp;<span>string</span>&nbsp;Put&lt;T&gt;(T&nbsp;data) { &nbsp;&nbsp;&nbsp;&nbsp;<span>using</span>&nbsp;(<span>var</span>&nbsp;httpClient&nbsp;=&nbsp;<span>new</span>&nbsp;<span>HttpClient</span>()) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>var</span>&nbsp;mediaType&nbsp;=&nbsp;<span>new</span>&nbsp;<span>MediaTypeHeaderValue</span>(<span>&quot;application/json&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>var</span>&nbsp;jsonSerializerSettings&nbsp;=&nbsp;<span>new</span>&nbsp;<span>JsonSerializerSettings</span>(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>var</span>&nbsp;jsonFormatter&nbsp;=&nbsp;<span>new</span>&nbsp;<span>JsonNetFormatter</span>(jsonSerializerSettings); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>var</span>&nbsp;requestMessage&nbsp;=&nbsp;<span>new</span>&nbsp;<span>HttpRequestMessage</span>&lt;T&gt;(data,&nbsp;mediaType,&nbsp;<span>new</span>&nbsp;<span>MediaTypeFormatter</span>[]&nbsp;{&nbsp;jsonFormatter&nbsp;}); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>var</span>&nbsp;result&nbsp;=&nbsp;httpClient.PutAsync(_endpoint,&nbsp;requestMessage.Content).Result; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>return</span>&nbsp;result.Content.ReadAsStringAsync().Result; &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> 2012-02-23T12:59:01-05:004847393http://forums.asp.net/p/1773007/4847393.aspx/1?Re+How+to+correctly+use+PostAsync+and+PutAsync+Re: How to correctly use PostAsync and PutAsync? <p>I would encourage you to go and have a look at C# Async CTP. You can get it today and build apps with it. It has go-live licence as well and C# 5 will have the features inside that CTP.</p> <p>With async CTP, you will be able to write asyncronous code just like you write your syncronous code. I am not a good enough on that to give samples but you can do the following AFAIK:</p> <pre class="prettyprint">var result = await httpClient.PutAsync(_endpoint, requestMessage.Content); return await result.Content.ReadAsStringAsync();</pre> 2012-02-23T13:32:29-05:004847443http://forums.asp.net/p/1773007/4847443.aspx/1?Re+How+to+correctly+use+PostAsync+and+PutAsync+Re: How to correctly use PostAsync and PutAsync? <p>First of all, are generic methods supported in the Web API? I think I read somewhere they currently are not?<br> <br> What are you trying to accomplish with the method btw? You are accepting a generic class then formatting it into a json string.&nbsp; Why not just use JsonValue? What kind of data are you doing a PUT with btw?<br> <br> But heres a modified example of how you can leverage async today, but I wrote the example without the generic support.<br> The trick is to make the API method return a Task, then you are not blocking the request thread when waiting for the client to finish.</p> <pre class="prettyprint">public Task&lt;string&gt; Put(string data) { var mediaType = new MediaTypeHeaderValue(&quot;application/json&quot;); var jsonSerializerSettings = new JsonSerializerSettings(); var jsonFormatter = new JsonNetFormatter(jsonSerializerSettings); var requestMessage = new HttpRequestMessage&lt;T&gt;(data, mediaType, new MediaTypeFormatter[] { jsonFormatter }); var httpClient = new HttpClient() return httpClient.PutAsync(_endpoint, requestMessage.Content).ContinueWith(httpResponseMessage =&gt; { return httpResponseMessage.Result.Content.ReadAsStringAsync(); }); }</pre> 2012-02-23T13:58:51-05:004847521http://forums.asp.net/p/1773007/4847521.aspx/1?Re+How+to+correctly+use+PostAsync+and+PutAsync+Re: How to correctly use PostAsync and PutAsync? <p>Thanks for the replies guys, but I think that my problem is not with sync/async.</p> <p>I would love to use the new await keyword, but right now, I don't want to be building against the .NET 4.5 Developer Preview.</p> <p>Back to the issue.</p> <p>Even if my code was blocking the thread until the response was returned, the code would still continue (eventually). &nbsp;I'm posting to a local Web API service on another port, and my GET and DELETE actions are instantaneous. &nbsp;So something is fundamentally wrong with my code, causing it to hang. &nbsp;I think it's on the client end, because I'm pretty sure the request never actually hits the service on the other end.</p> <p>All I'm trying to do is serialize a POCO and PUT it to the Web API to update a record in a database. &nbsp;My put handler in the Web API controller looks like this:</p> <pre>[<span>HttpPut</span>] <span>public</span>&nbsp;<span>void</span>&nbsp;PutMyClass(<span>int</span>&nbsp;id,&nbsp;<span>MyClass myClass</span>) { &nbsp;&nbsp;&nbsp;&nbsp;myClass.MyClassID&nbsp;=&nbsp;id; &nbsp;&nbsp;&nbsp;&nbsp;<span>if</span>&nbsp;(!_myClassRepository.UpdateMyClass(myClass)) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>throw</span>&nbsp;<span>new</span>&nbsp;<span>HttpResponseException</span>(<span>HttpStatusCode</span>.NotFound); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> <p>Any other ideas?</p> 2012-02-23T14:40:47-05:004847528http://forums.asp.net/p/1773007/4847528.aspx/1?Re+How+to+correctly+use+PostAsync+and+PutAsync+Re: How to correctly use PostAsync and PutAsync? <p>So the API you showed in your first post is functioning as a kind of reverse proxy?</p> <p>What are you serializing your POCO as when posting? If it's JSON, then instead of a generic method just use JsonValue and send that on to your backend service?</p> <p>Try changing your method to not be generic, people have had problems with generic methods on a controller:<br> http://forums.asp.net/t/1770829.aspx/1?Using&#43;generics&#43;in&#43;ApiController&#43;controller&#43;</p> <p></p> 2012-02-23T14:46:26-05:004847624http://forums.asp.net/p/1773007/4847624.aspx/1?Re+How+to+correctly+use+PostAsync+and+PutAsync+Re: How to correctly use PostAsync and PutAsync? <p>Thanks for another reply SiggiGG.</p> <p>I don't think generics are my problem. &nbsp;I tried removing all the generic code and just doing a post to the service and it still hangs.</p> <p>I also tried re-including the async code (in .NET 4), and I still have the same problem.</p> <p>Can you elaborate on the JsonValue mechanism you mentioned?</p> 2012-02-23T15:33:26-05:004847638http://forums.asp.net/p/1773007/4847638.aspx/1?Re+How+to+correctly+use+PostAsync+and+PutAsync+Re: How to correctly use PostAsync and PutAsync? <p></p> <blockquote><span class="icon-blockquote"></span> <h4>skippyfire</h4> <p></p> <p>Thanks for another reply SiggiGG.</p> <p>I don't think generics are my problem. &nbsp;I tried removing all the generic code and just doing a post to the service and it still hangs.</p> <p>I also tried re-including the async code (in .NET 4), and I still have the same problem.</p> <p>Can you elaborate on the JsonValue mechanism you mentioned?</p> <p></p> </blockquote> <p></p> <p>Are you using the JsonNetFormatter from here?</p> <p><a href="http://code.msdn.microsoft.com/Using-JSONNET-with-ASPNET-b2423706">http://code.msdn.microsoft.com/Using-JSONNET-with-ASPNET-b2423706</a></p> <p>If Yes, then there seems to be a problem in the WriteToStreamAsync method of this formatter. I was able to repro this issue. This method seems to work fine while writing the response on the Service side, but has problems writing on the Client side. I have notified Henrik regarding this. Will post updates.</p> <p><strong>[UPDATE]</strong> : The blog has been updated with the fix to the JsonNetFormatter. You should be able to use it now.</p> 2012-02-23T15:40:49-05:004847666http://forums.asp.net/p/1773007/4847666.aspx/1?Re+How+to+correctly+use+PostAsync+and+PutAsync+Re: How to correctly use PostAsync and PutAsync? <p></p> <blockquote><span class="icon-blockquote"></span> <h4>skippyfire</h4> Can you elaborate on the JsonValue mechanism you mentioned?</blockquote> <p></p> <p>JsonValue is a really handy type to deal with JSON data in a loosely typed way.</p> <p>In your case you can do something like this:</p> <pre class="prettyprint">public void Post(JsonValue value) { var httpClient = new HttpClient(); httpClient.BaseAddress = new Uri(&quot;http://localhost:31724&quot;); StringContent content = new System.Net.Http.StringContent(value.ToString(), Encoding.UTF8, &quot;application/json&quot;); var result = httpClient.PutAsync(&quot;api/Values&quot;, content).Result; }</pre> 2012-02-23T15:54:07-05:004847678http://forums.asp.net/p/1773007/4847678.aspx/1?Re+How+to+correctly+use+PostAsync+and+PutAsync+Re: How to correctly use PostAsync and PutAsync? <p>Stupid question: How do I new up a JsonValue?</p> <p>It looks like the constructor(s) are not public and I don't see any static methods that would let me &quot;load&quot; a JsonValue from a concrete POCO.</p> <p>Is JsonObject what I want instead?</p> 2012-02-23T15:59:49-05:004847721http://forums.asp.net/p/1773007/4847721.aspx/1?Re+How+to+correctly+use+PostAsync+and+PutAsync+Re: How to correctly use PostAsync and PutAsync? <p>You can use JsonValue.Parse(string json) to create a new instance.</p> <p>Just curious, why do you need to new up a JsonValue? When posting data you can just post normal POCO classes.&nbsp; I was just showing you how to use JsonValue to receive loosely typed data.</p> <p></p> 2012-02-23T16:22:53-05:004847755http://forums.asp.net/p/1773007/4847755.aspx/1?Re+How+to+correctly+use+PostAsync+and+PutAsync+Re: How to correctly use PostAsync and PutAsync? <p>Sorry, I don't think I explained it well.</p> <p>I have a Project that acts as my client for the service. &nbsp;So multiple front ends can reference the same client project.</p> <p>The client project will take data from MVC, WinForms, WPF, whatever, and post the data for you. &nbsp;So the client project takes a POCO, and posts it to the Web API.</p> <p>For now, I'm not posting data from a web page directly to the service. &nbsp;That is why I'm using PostAsync and PutAsync. &nbsp;I'm using those to send data to the Web API service. &nbsp;I really don't care how the data is serialized, I was just trying to use a JSON one in this case.</p> <p>Is my problem more clear now? &nbsp;Should I be using HttpClient to post/put data like this? &nbsp;Or is there something easier I can/should use, at least until the Web API is more baked?</p> 2012-02-23T16:41:19-05:004847789http://forums.asp.net/p/1773007/4847789.aspx/1?Re+How+to+correctly+use+PostAsync+and+PutAsync+Re: How to correctly use PostAsync and PutAsync? <p>Ah ok that explains it :) I thought you had a &quot;front end&quot; Web API that was re-posting data to a backend one (I assumed for some security reasons).&nbsp; Now the generic code makes more sense ;)</p> <p>And yes you should absolutely use HttpClient to interect with Web APIs, it's a great client.</p> <p>If you debug your client code, where is it hanging? Is the URL in your _endpoint variable correct?</p> <p>There are a few ways to encode a POCO object into JSON for PUT/POST, and afaik your method of using the HttpRequestMessage should work.<br> You can also use StringContent or StreamContent, and a Json serializer to encode your class.</p> 2012-02-23T17:02:51-05:004847831http://forums.asp.net/p/1773007/4847831.aspx/1?Re+How+to+correctly+use+PostAsync+and+PutAsync+Re: How to correctly use PostAsync and PutAsync? <p>It hangs when it is trying to get the result from the request.</p> <p>My endpoint is valid for GETs and DELETEs.</p> <p>Not sure what else it could be. &nbsp;Has anyone posted any sample for making POST and PUT requests FROM the Web API?</p> 2012-02-23T17:33:50-05:004847834http://forums.asp.net/p/1773007/4847834.aspx/1?Re+How+to+correctly+use+PostAsync+and+PutAsync+Re: How to correctly use PostAsync and PutAsync? <p>I think you missed my post in this discussion thread:&nbsp;<a href="http://forums.asp.net/post/4847638.aspx">http://forums.asp.net/post/4847638.aspx</a></p> 2012-02-23T17:35:57-05:004847835http://forums.asp.net/p/1773007/4847835.aspx/1?Re+How+to+correctly+use+PostAsync+and+PutAsync+Re: How to correctly use PostAsync and PutAsync? <p>FYI, I did try this from a simple HTML page with some jQuery, and I was able to make a PUT request. &nbsp;So the problem is definitely client side for me.</p> 2012-02-23T17:36:46-05:004847854http://forums.asp.net/p/1773007/4847854.aspx/1?Re+How+to+correctly+use+PostAsync+and+PutAsync+Re: How to correctly use PostAsync and PutAsync? <p>Interesting.&nbsp; Please try using a StringContent or StreamContent class instead of the HttpRequestMessage you are doing.</p> <p></p> 2012-02-23T17:51:34-05:004847902http://forums.asp.net/p/1773007/4847902.aspx/1?Re+How+to+correctly+use+PostAsync+and+PutAsync+Re: How to correctly use PostAsync and PutAsync? <p>SkippyFire, I have posted the reason behind the issue here:&nbsp;<a href="http://forums.asp.net/post/4847638.aspx">http://forums.asp.net/post/4847638.aspx</a><a href="http://forums.asp.net/post/4847638.aspx"></a></p> 2012-02-23T18:30:05-05:004847918http://forums.asp.net/p/1773007/4847918.aspx/1?Re+How+to+correctly+use+PostAsync+and+PutAsync+Re: How to correctly use PostAsync and PutAsync? <p>Hi Kiran,</p> <p>&nbsp; Yes I did miss that, twice apparently! &nbsp;Thank you for pointing it out to me again. &nbsp;I'm going to try reverting to the default Formatter and see if that works.</p> <p>Thanks again.</p> 2012-02-23T18:44:22-05:004852279http://forums.asp.net/p/1773007/4852279.aspx/1?Re+How+to+correctly+use+PostAsync+and+PutAsync+Re: How to correctly use PostAsync and PutAsync? <p>I have simillar issues :</p> <p>I have code like this on serverSide :</p> <pre class="prettyprint">public HttpResponseMessage&lt;Contact&gt; Post(HttpRequestMessage&lt;Contact&gt; request) { var pero = request.Content.ReadAsAsync(typeof(Contact)).Result;</pre> <p>Problem is that pero variable is always null</p> 2012-02-27T08:01:23-05:004852346http://forums.asp.net/p/1773007/4852346.aspx/1?Re+How+to+correctly+use+PostAsync+and+PutAsync+Re: How to correctly use PostAsync and PutAsync? <p></p> <blockquote><span class="icon-blockquote"></span> <h4>logic_rabbit</h4> <p></p> <p>I have simillar issues :</p> <p>I have code like this on serverSide :</p> <pre class="prettyprint">public HttpResponseMessage&lt;Contact&gt; Post(HttpRequestMessage&lt;Contact&gt; request) { var pero = request.Content.ReadAsAsync(typeof(Contact)).Result;</pre> <p>Problem is that pero variable is always null</p> <p></blockquote></p> <p>logic_rabbit, you can acutally get the request from the ApiController instance:</p> <pre class="prettyprint"> public HttpResponseMessage&lt;Contact&gt; Post() { var pero = <em><strong><span style="text-decoration: underline;">this.Request.</span></strong></em>Content.ReadAsAsync(typeof(Contact)).Result;</pre> <p></p> </blockquote> 2012-02-27T08:37:38-05:00