Controlador MVC: obtener el objeto JSON del cuerpo HTTP

Tenemos una aplicación MVC (MVC4) que a veces puede obtener un evento JSON PUBLICADO por un tercero en nuestra URL específica (” http://server.com/events/ “). El evento JSON está en el cuerpo del HTTP POST y el cuerpo es estrictamente JSON ( Content-Type: application/json , no un formulario post con JSON en algún campo de cadena).

¿Cómo puedo recibir el cuerpo JSON dentro del cuerpo del controlador? Intenté lo siguiente pero no obtuve nada

[Editar] : Cuando digo que no obtuve nada, quise decir que jsonBody siempre es nulo independientemente de si lo defino como Object o como string .

 [HttpPost] // this maps to http://server.com/events/ // why is jsonBody always null ?! public ActionResult Index(int? id, string jsonBody) { // Do stuff here } 

Tenga en cuenta que sé si doy declarar el método con un parámetro de entrada fuertemente tipado, MVC hace todo el análisis sintáctico y el filtrado, es decir,

 // this tested to work, jsonBody has valid json data // that I can deserialize using JSON.net public ActionResult Index(int? id, ClassType847 jsonBody) { ... } 

Sin embargo, el JSON que obtenemos es muy variado, por lo que no queremos definir (y mantener) cientos de clases diferentes para cada variante JSON.

Estoy probando esto con el siguiente comando curl (con una variante del JSON aquí)

 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 }}} 

Parece que si

  • Content-Type: application/json y
  • si el cuerpo POST no está estrechamente ligado a la clase de objeto de entrada del controlador

Entonces MVC realmente no une el cuerpo POST a ninguna clase en particular. Tampoco puede obtener el cuerpo POST como un parámetro del ActionResult (sugerido en otra respuesta). Lo suficientemente justo. Debe obtenerlo de la secuencia de solicitud usted mismo y procesarlo.

 [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(json) } catch (Exception ex) { // Try and handle malformed POST body return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } //do stuff } 

use Request.Form para obtener los datos

Controlador:

  [HttpPost] public ActionResult Index(int? id) { string jsonData= Request.Form[0]; // The data from the POST } 

Escribo esto para probar

Ver:

   

y escribir Request.Form[0] o Request.Params[0] en el controlador puede obtener los datos.

No escribo la

tag

a la vista.

Una vez que defina una clase (MyDTOClass) que indique lo que espera recibir, debe ser tan simple como …

 public ActionResult Post([FromBody]MyDTOClass inputData){ ... do something with input data ... } 

Gracias a Julias:

Analizando Json .Net Web Api

Asegúrese de que su solicitud se envíe con el encabezado http:

Tipo de contenido: application / json

puedes obtener la cadena json como un ActionResult de tu ActionResult y luego serializarla usando JSON.Net

AQUÍ se muestra un ejemplo


Para recibirlo en forma serializada como parámetro de la acción del controlador, debe escribir un archivador de modelo personalizado o un filtro de acción (OnActionExecuting) para que la cadena json se serialice en el modelo que le guste y esté disponible dentro del controlador. cuerpo para su uso.


AQUÍ hay una implementación que usa el objeto dynamic