70

I have an MVC API controller with the following action.

I don't understand how to read the actual data/body of the Message?

[HttpPost] public void Confirmation(HttpRequestMessage request) { var content = request.Content; } 
3
  • 2
    What do you get from request.Content? Commented Jul 31, 2013 at 13:22
  • I see all the headers and the content length, but where is the data? Commented Jul 31, 2013 at 13:23
  • You can check multiple examples here: codingfusion.com/Post/… Commented Aug 2, 2023 at 11:15

4 Answers 4

97

From this answer:

[HttpPost] public void Confirmation(HttpRequestMessage request) { var content = request.Content; string jsonContent = content.ReadAsStringAsync().Result; } 

Note: As seen in the comments, this code could cause a deadlock and should not be used. See this blog post for more detail.

Sign up to request clarification or add additional context in comments.

7 Comments

From developer point of view, using aync may not be a better option in case if you want to debug or wait till the operation is complete to view data.
People, please read @ToddMenier's comment: DO NOT use this code in production. It's appeared in our code and has deadlocked.
This is the wrong solution. Look at @Zebing Lin's answer
So how should this answer be edited to not cause a deadlock? Please update the answer instead of refering the reader to an external site.
|
33
using System.IO; string requestFromPost; using( StreamReader reader = new StreamReader(HttpContext.Current.Request.InputStream) ) { reader.BaseStream.Position = 0; requestFromPost = reader.ReadToEnd(); } 

4 Comments

Request.Content is a stream. Depending on when precisely your code ran, the stream may have already been consumed.
This works for MVC, while accepted answer for Web Api only
The BaseStream.Position = 0 clued me into the fact that if the content is eaten by the framework to fill in a parameter for the HttpPost method, that the stream might be reset. Which it was. Thank you.
This worked for me as well, should be the accepted answer.
15

I suggest that you should not do it like this. Action methods should be designed to be easily unit-tested. In this case, you should not access data directly from the request, because if you do it like this, when you want to unit test this code you have to construct a HttpRequestMessage.

You should do it like this to let MVC do all the model binding for you:

[HttpPost] public void Confirmation(YOURDTO yourobj)//assume that you define YOURDTO elsewhere { //your logic to process input parameters. } 

In case you do want to access the request. You just access the Request property of the controller (not through parameters). Like this:

[HttpPost] public void Confirmation() { var content = Request.Content.ReadAsStringAsync().Result; } 

In MVC, the Request property is actually a wrapper around .NET HttpRequest and inherit from a base class. When you need to unit test, you could also mock this object.

3 Comments

And in case you have HttpGet? If I use Request.Content.ReadAsStringAsync().Result; it doesn't work!
@ayasha: with HttpGet, the parameters should come from query string instead of request body.
@ayasha: I have also updated the answer. Just realized it did not work before
3

In case you want to cast to a class and not just a string:

YourClass model = await request.Content.ReadAsAsync<YourClass>(); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.