Reputation: 13752
We have an MVC (MVC4) application which at times might get a JSON events POSTed from a 3rd party to our specific URL ("http://server.com/events/"). The JSON event is in the body of the HTTP POST and the body is strictly JSON (Content-Type: application/json
- not a form-post with JSON in some string field).
How can I receive the JSON body inside the controller's body? I tried the following but didn't get anything
[Edit]: When I say didn't get anything I meant that jsonBody is always null regardless of whether I define it as Object
or string
.
[HttpPost]
// this maps to http://server.com/events/
// why is jsonBody always null ?!
public ActionResult Index(int? id, string jsonBody)
{
// Do stuff here
}
Note that I know if I give declare the method with a strongly typed input parameter, MVC does the whole parsing and filtering i.e.
// this tested to work, jsonBody has valid json data
// that I can deserialize using JSON.net
public ActionResult Index(int? id, ClassType847 jsonBody) { ... }
However, the JSON we get is very varied, so we don't want to define (and maintain) hundreds of different classes for each JSON variant.
I'm testing this by the following curl
command (with one variant of the JSON here)
curl -i -H "Host: localhost" -H "Content-Type: application/json" -X POST http://localhost/events/ -d '{ "created": 1326853478, "data": { "object": { "num_of_errors": 123, "fail_count": 3 }}}
Upvotes: 88
Views: 193030
Reputation: 642
If you are sending raw data from postman body with
Content-Type: application/json
then it's consider as Stream data. please find the following way to get that.
[HttpPost]
public async Task<IActionResult> Post()
{
string Header_Value = string.Empty;
if (Request.Headers.TryGetValue("Sequeritykey", out var headerValues))
{
Header_Value = headerValues;
}
StreamReader requestReader = new StreamReader(Request.Body);
JObject request = JObject.Parse(await requestReader.ReadToEndAsync());
return Ok();
}
Upvotes: 2
Reputation: 17566
I've been trying to get my ASP.NET MVC controller to parse some model that i submitted to it using Postman.
I needed the following to get it to work:
controller action
[HttpPost]
[PermitAllUsers]
[Route("Models")]
public JsonResult InsertOrUpdateModels(Model entities)
{
// ...
return Json(response, JsonRequestBehavior.AllowGet);
}
a Models class
public class Model
{
public string Test { get; set; }
// ...
}
headers for Postman's request, specifically, Content-Type
json in the request body
Upvotes: 3
Reputation: 13752
It seems that if
Content-Type: application/json
andThen MVC doesn't really bind the POST body to any particular class. Nor can you just fetch the POST body as a param of the ActionResult (suggested in another answer). Fair enough. You need to fetch it from the request stream yourself and process it.
[HttpPost]
public ActionResult Index(int? id)
{
Stream req = Request.InputStream;
req.Seek(0, System.IO.SeekOrigin.Begin);
string json = new StreamReader(req).ReadToEnd();
InputClass input = null;
try
{
// assuming JSON.net/Newtonsoft library from http://json.codeplex.com/
input = JsonConvert.DeserializeObject<InputClass>(json)
}
catch (Exception ex)
{
// Try and handle malformed POST body
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
//do stuff
}
Update:
for Asp.Net Core, you have to add [FromBody]
attrib beside your param name in your controller action for complex JSON data types:
[HttpPost]
public ActionResult JsonAction([FromBody]Customer c)
Also, if you want to access the request body as string to parse it yourself, you shall use Request.Body
instead of Request.InputStream
:
Stream req = Request.Body;
req.Seek(0, System.IO.SeekOrigin.Begin);
string json = new StreamReader(req).ReadToEnd();
Upvotes: 174
Reputation: 4297
Once you define a class (MyDTOClass) indicating what you expect to receive it should be as simple as...
public ActionResult Post([FromBody]MyDTOClass inputData){
... do something with input data ...
}
Thx to Julias:
Make sure your request is sent with the http header:
Content-Type: application/json
Upvotes: 1
Reputation: 594
use Request.Form
to get the Data
Controller:
[HttpPost]
public ActionResult Index(int? id)
{
string jsonData= Request.Form[0]; // The data from the POST
}
I write this to try
View:
<input type="button" value="post" id="btnPost" />
<script type="text/javascript">
$(function () {
var test = {
number: 456,
name: "Ryu"
}
$("#btnPost").click(function () {
$.post('@Url.Action("Index", "Home")', JSON.stringify(test));
});
});
</script>
and write Request.Form[0]
or Request.Params[0]
in controller can get the data.
I don't write <form> tag
in view.
Upvotes: 6
Reputation:
you can get the json string as a param of your ActionResult
and afterwards serialize it using JSON.Net
HERE an example is being shown
in order to receive it in the serialized form as a param of the controller action you must either write a custom model binder or a Action filter (OnActionExecuting) so that the json string is serialized into the model of your liking and is available inside the controller body for use.
HERE is an implementation using the dynamic object
Upvotes: 0