Passing XDocument as message contenthttp://forums.asp.net/t/1770887.aspx/1?Passing+XDocument+as+message+contentFri, 17 Feb 2012 22:23:35 -050017708874838128http://forums.asp.net/p/1770887/4838128.aspx/1?Passing+XDocument+as+message+contentPassing XDocument as message content <p>In the wcf version I was passing XDocuments back and forth between my server &amp; httpclient by doing</p> <pre class="prettyprint">new HttpRequestMessage() { Content = new StringContent(doc.ToString()) } and then usign ReadAsStreamAsync() to pull it out on the server side</pre> <p>As of the beta this no longer works. What is the recommended way to do this?</p> 2012-02-17T19:03:24-05:004838137http://forums.asp.net/p/1770887/4838137.aspx/1?Re+Passing+XDocument+as+message+contentRe: Passing XDocument as message content <p>Can you elaborate more as to what kind of behavior are you seeing on the Server side?</p> <p>I am guessing you are trying to read the request's content at anAction of&nbsp;a controller...how does your Action look like?</p> <p>&nbsp;</p> <p>Thanks, Kiran</p> 2012-02-17T19:10:19-05:004838194http://forums.asp.net/p/1770887/4838194.aspx/1?Re+Passing+XDocument+as+message+contentRe: Passing XDocument as message content You need to set the encoding and mediaType parameters on StringContent. Setting the mediaType parameter to &quot;application/xml&quot; should work. By default the media type is &quot;text/plain.&quot; 2012-02-17T19:53:52-05:004838225http://forums.asp.net/p/1770887/4838225.aspx/1?Re+Passing+XDocument+as+message+contentRe: Passing XDocument as message content <p>When I call the client like</p> <pre class="prettyprint">var post = client.PostAsync(&quot;http://localhost:32510/api/something&quot;, new StringContent(doc.ToString()));</pre> <p>I am not able to break into any of my code on the server side, instead I just get a 500</p> <pre class="prettyprint"> var responseDoc = post.Result.Content.ReadAsStringAsync().Result; </pre> <p>It looks like the response comes back as a JSON serialized exception?</p> <pre class="prettyprint">{"ExceptionType":"System.InvalidOperationException","Message":"No 'MediaTypeFormatter' is available to read an object of type 'HttpRequestMessage' with the media type 'text\/plain'.","StackTrace":" at System.Net.Http.ObjectContent.SelectAndValidateReadFormatter(Boolean acceptNullFormatter)\u000d\u000a at System.Net.Http.ObjectContent.ReadAsyncInternal[T](Boolean allowDefaultIfNoFormatter)\u000d\u000a at System.Web.Http.ModelBinding.RequestContentReader.ReadWholeBodyAsync(HttpActionContext actionContext, Type modelType)\u000d\u000a at System.Web.Http.ModelBinding.RequestContentReader.ReadContentAsync(HttpActionContext actionContext)\u000d\u000a at System.Web.Http.ModelBinding.DefaultActionValueBinder.BindValuesAsync(HttpActionContext actionContext, CancellationToken cancellationToken)\u000d\u000a at System.Web.Http.ApiController.&lt;&gt;c__DisplayClass3.<executeasync>b__0()\u000d\u000a at System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)\u000d\u000a at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncInternal(HttpRequestMessage request, CancellationToken cancellationToken)\u000d\u000a at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)"} </executeasync></pre> 2012-02-17T20:42:31-05:004838229http://forums.asp.net/p/1770887/4838229.aspx/1?Re+Passing+XDocument+as+message+contentRe: Passing XDocument as message content <p>Yes, the default formatter is the JsonFormatter. Unless you specify media types in your Accept header, you should expect a JSON response.</p> <p>Try using:</p> <pre class="prettyprint">new StringContent(doc.ToString(), System.Text.Encoding.UTF8, &quot;application/xml&quot;);</pre> 2012-02-17T20:45:02-05:004838230http://forums.asp.net/p/1770887/4838230.aspx/1?Re+Passing+XDocument+as+message+contentRe: Passing XDocument as message content <p><strong>** EDIT: nevermind this, I see another thread answers this question**</strong></p> <p>I had tried doing that but then on the server side I get a NRE because request.Content is null</p> <p></p> <pre class="prettyprint">public HttpResponseMessage SomeApiMethod(HttpRequestMessage request) { var doc = XDocument.Parse(request.Content.ReadAsStringAsync().Result); }</pre> 2012-02-17T20:46:24-05:004838231http://forums.asp.net/p/1770887/4838231.aspx/1?Re+Passing+XDocument+as+message+contentRe: Passing XDocument as message content <p>Also, keep in mind that calling .Result immediately can lead to deadlocks. I don't remember the link at the moment.</p> 2012-02-17T20:46:37-05:004838233http://forums.asp.net/p/1770887/4838233.aspx/1?Re+Passing+XDocument+as+message+contentRe: Passing XDocument as message content <p>Ah, I see. Model binding isn't working on HttpRequestMessage in the method parameters in the beta, though I think that is coming again. Use this.Request property on the ApiController. See this thread:&nbsp;<a href="http://forums.asp.net/t/1770894.aspx/1?request&#43;Content&#43;ReadAsync&#43;Result&#43;returns&#43;null">http://forums.asp.net/t/1770894.aspx/1?request&#43;Content&#43;ReadAsync&#43;Result&#43;returns&#43;null</a>.</p> 2012-02-17T20:47:41-05:004838235http://forums.asp.net/p/1770887/4838235.aspx/1?Re+Passing+XDocument+as+message+contentRe: Passing XDocument as message content <p>really, that is scary, what's the correct way?</p> 2012-02-17T20:48:49-05:004838237http://forums.asp.net/p/1770887/4838237.aspx/1?Re+Passing+XDocument+as+message+contentRe: Passing XDocument as message content <p></p> <blockquote><span class="icon-blockquote"></span> <h4>chrisortman</h4> <p></p> <p>really, that is scary, what's the correct way?</p> <p></p> </blockquote> <p></p> <p>In .NET 4.5, you should use the async/await keywords. In .NET 4.0, you should probably go with the .ContinueWith() to continue your execution chain. Henrik has posted <a href="http://blogs.msdn.com/b/henrikn/archive/2012/02/11/httpclient-is-here.aspx"> examples</a>.</p> 2012-02-17T20:51:26-05:004838253http://forums.asp.net/p/1770887/4838253.aspx/1?Re+Passing+XDocument+as+message+contentRe: Passing XDocument as message content <pre class="prettyprint">public Task&lt;HttpResponseMessage&gt; SomeApiMethod() { return Request.Content.ReadAsStreamAsync().ContinueWith(s =&gt; { var doc = XDocument.Load(s.Result);</pre> <p>Throws: Cannot access a closed Stream, but ReadAsString() works fine.</p> 2012-02-17T21:08:12-05:004838256http://forums.asp.net/p/1770887/4838256.aspx/1?Re+Passing+XDocument+as+message+contentRe: Passing XDocument as message content <p>That sounds like a bug. It shouldn't have closed if it hasn't been read.</p> 2012-02-17T21:11:54-05:004838287http://forums.asp.net/p/1770887/4838287.aspx/1?Re+Passing+XDocument+as+message+contentRe: Passing XDocument as message content <pre class="prettyprint">It would be helpful if you could past the entire Action method here. I say this because, a similar scenario like yours works for me: [HttpPost] public Task&lt;string&gt; TestActionReadingAsStream() { return Request.Content.ReadAsStreamAsync().ContinueWith&lt;string&gt;(tsk =&gt; { string value = null; using (StreamReader reader = new StreamReader(tsk.Result)) { value = reader.ReadToEnd(); } return value; }); }</pre> <p>&nbsp;</p> <p>&nbsp;</p> 2012-02-17T22:23:35-05:00