Reputation: 2120
How do I get access to the JSON from a controller method in a WebApi? For example below I want access to both the de-serialized customer passed in as a parameter, and the serialized customer.
public HttpResponseMessage PostCustomer(Customer customer)
{
if (ModelState.IsValid)
{
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, customer);
response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = customer.Id }));
return response;
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
}
Upvotes: 3
Views: 1825
Reputation: 3341
I was trying to do something very similar, but wasn't able to find a way to inject a handler directly into Web API in the proper place. It seems delegated message handlers fall between the deserialize/serialize step and the routing step (something they don't show you in all those Web API pipeline diagrams).
However I found that the OWIN pipeline precedes the Web API pipeline. So by adding OWIN to your Web API project and creating a custom middleware class, you can handle requests before they hit the Web API pipeline and after they leave the Web API pipeline, which is very handy. And will definitely get you the results you're looking for.
Hope this helps.
Upvotes: 0
Reputation: 1893
You can't get the parsed JSON, but you can get the content and parse it yourself. Try this:
public async Task PostCustomer(Customer customer)
{
var json = Newtonsoft.Json.JsonConvert.DeserializeObject(await this.Request.Content.ReadAsStringAsync());
///You can deserialize to any object you need or simply a Dictionary<string,object> so you can check the key value pairs.
}
Upvotes: 0
Reputation: 19321
You will not be able to get the JSON in controller. In ASP.NET Web API pipeline, binding happens before the action method executes. Media formatter would have read the request body JSON (which is a read-once stream) and emptied the contents by the time the execution comes to your action method. But if you read the JSON from a component running in the pipeline before the binding, say a message handler, you will be able to read it like this. If you must get the JSON in action method, you can store it in the properties dictionary.
public class MessageContentReadingHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
var content = await request.Content.ReadAsStringAsync();
// At this point 'content' variable has the raw message body
request.Properties["json"] = content;
return await base.SendAsync(request, cancellationToken);
}
}
From the action method, you can retrieve JSON string like this:
public HttpResponseMessage PostCustomer(Customer customer)
{
string json = (string)Request.Properties["json"];
}
Upvotes: 5