You need to set the encoding and mediaType parameters on StringContent. Setting the mediaType parameter to "application/xml" should work. By default the media type is "text/plain."
var post = client.PostAsync("http://localhost:32510/api/something",
new StringContent(doc.ToString()));
I am not able to break into any of my code on the server side, instead I just get a 500
var responseDoc = post.Result.Content.ReadAsStringAsync().Result;
It looks like the response comes back as a JSON serialized exception?
{"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.<>c__DisplayClass3.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)"}
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
examples.
chrisortman
Member
38 Points
23 Posts
Passing XDocument as message content
Feb 17, 2012 07:03 PM|LINK
In the wcf version I was passing XDocuments back and forth between my server & httpclient by doing
new HttpRequestMessage() { Content = new StringContent(doc.ToString()) } and then usign ReadAsStreamAsync() to pull it out on the server sideAs of the beta this no longer works. What is the recommended way to do this?
Kiran Challa
Participant
1460 Points
285 Posts
Microsoft
Re: Passing XDocument as message content
Feb 17, 2012 07:10 PM|LINK
Can you elaborate more as to what kind of behavior are you seeing on the Server side?
I am guessing you are trying to read the request's content at anAction of a controller...how does your Action look like?
Thanks, Kiran
Kiran Challa
panesofglass
Participant
758 Points
242 Posts
Re: Passing XDocument as message content
Feb 17, 2012 07:53 PM|LINK
chrisortman
Member
38 Points
23 Posts
Re: Passing XDocument as message content
Feb 17, 2012 08:42 PM|LINK
When I call the client like
var post = client.PostAsync("http://localhost:32510/api/something", new StringContent(doc.ToString()));I am not able to break into any of my code on the server side, instead I just get a 500
It looks like the response comes back as a JSON serialized exception?
{"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.<>c__DisplayClass3.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)"} panesofglass
Participant
758 Points
242 Posts
Re: Passing XDocument as message content
Feb 17, 2012 08:45 PM|LINK
Yes, the default formatter is the JsonFormatter. Unless you specify media types in your Accept header, you should expect a JSON response.
Try using:
chrisortman
Member
38 Points
23 Posts
Re: Passing XDocument as message content
Feb 17, 2012 08:46 PM|LINK
** EDIT: nevermind this, I see another thread answers this question**
I had tried doing that but then on the server side I get a NRE because request.Content is null
public HttpResponseMessage SomeApiMethod(HttpRequestMessage request) { var doc = XDocument.Parse(request.Content.ReadAsStringAsync().Result); }panesofglass
Participant
758 Points
242 Posts
Re: Passing XDocument as message content
Feb 17, 2012 08:46 PM|LINK
Also, keep in mind that calling .Result immediately can lead to deadlocks. I don't remember the link at the moment.
panesofglass
Participant
758 Points
242 Posts
Re: Passing XDocument as message content
Feb 17, 2012 08:47 PM|LINK
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: http://forums.asp.net/t/1770894.aspx/1?request+Content+ReadAsync+Result+returns+null.
chrisortman
Member
38 Points
23 Posts
Re: Passing XDocument as message content
Feb 17, 2012 08:48 PM|LINK
really, that is scary, what's the correct way?
panesofglass
Participant
758 Points
242 Posts
Re: Passing XDocument as message content
Feb 17, 2012 08:51 PM|LINK
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 examples.