Getting raw POST/PUT body data from Request in a Web Api controller

Looking for a solution to get raw data (body) of a POST or PUT request in Web API? Here are two ways to do what you want. If you do not mind parsing the object on your own then the below way is a perfect fit for you. Here you skip using the built in web API object mapper and do the mapping yourself. Below is just how to get the raw post data. This is simple and will do the trick in most cases:

public HttpResponseMessage Post()
{
   var content = Request.Content.ReadAsByteArrayAsync();
}

The above examples and the examples in this post works both for PUT and POST verbs.

An alternative solution

As an alternative, if you do not wish to change the contract of your method, then there is another way. But I do not think it is as "clean" as the previous. However it lets you keep the method parameters.

SaveRawPostData.cs

Basically this solution is based on using a DelegatingHandler saving the post data. What I do not like about this solution is the pollution of the request. I wish to save the data, but I can only store it on the request like below:

public class SaveRawPostData : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, 
            System.Threading.CancellationToken cancellationToken)
    {
        request.Properties.Add("rawpostdata", request.Content.ReadAsStringAsync().Result);
        return base.SendAsync(request, cancellationToken);
    }
}

WebApiConfig.cs

The delegatinghandler needs to be added to the list of MessageHandlers where you configure Web Api. Most likely in WebApiConfig.cs:

config.MessageHandlers.Add(new SaveRawPostData());

ControllerExtensions.cs

In order to easily get the data I created a small extension method which can be used within a controller:

public static string GetRawPostData(this HttpControllerContext requestContext)
{
   return (string) requestContext.Request.Properties["rawpostdata"];
}

TestController (for yes! testing!)

By using the extension method above I can easily access the rawData through ControllerContext.GetRawPostData();. This gives me both an object and the raw postdata:

public class TestController : ApiController
{
    [HttpPost]
    public void DoTest(Person p)
    {
        var person = p;//parsed object
        var rawData = ControllerContext.GetRawPostData(); //raw data
    }
}

That is it!

This was my alternative solution to the problem. Do you have any comments then please write them below!