EDITAR : 31/10/2017
El mismo código / enfoque funcionará también para Asp.Net Core 2.0 . La principal diferencia es que, en asp.net core, tanto los controladores de API web como los controladores de Mvc se fusionan en un solo modelo de controlador. Por lo que su tipo de retorno podría ser IActionResult
o uno de ellos de aplicación (Ej: OkObjectResult
)
Utilizar
contentType:"application/json"
Debe usar el JSON.stringify
método para convertirlo a una cadena JSON cuando lo envíe,
Y la carpeta modelo enlazará los datos json a su objeto de clase.
El siguiente código funcionará bien (probado)
$(function () {
var customer = {contact_name :"Scott",company_name:"HP"};
$.ajax({
type: "POST",
data :JSON.stringify(customer),
url: "api/Customer",
contentType: "application/json"
});
});
Resultado
contentType
La propiedad le dice al servidor que estamos enviando los datos en formato JSON. Como enviamos una estructura de datos JSON, el enlace del modelo se realizará correctamente.
Si inspecciona los encabezados de la solicitud ajax, puede ver que el Content-Type
valor se establece como application/json
.
Si no especifica contentType explícitamente, utilizará el tipo de contenido predeterminado que es application/x-www-form-urlencoded;
Edite en noviembre de 2015 para abordar otros posibles problemas planteados en los comentarios
Publicar un objeto complejo
Supongamos que tiene una clase de modelo de vista compleja como su parámetro de método de acción de API web como este
public class CreateUserViewModel
{
public int Id {set;get;}
public string Name {set;get;}
public List<TagViewModel> Tags {set;get;}
}
public class TagViewModel
{
public int Id {set;get;}
public string Code {set;get;}
}
y su punto final de la API web es como
public class ProductController : Controller
{
[HttpPost]
public CreateUserViewModel Save([FromBody] CreateUserViewModel m)
{
// I am just returning the posted model as it is.
// You may do other stuff and return different response.
// Ex : missileService.LaunchMissile(m);
return m;
}
}
Al momento de escribir esto, ASP.NET MVC 6 es la última versión estable y en MVC6, tanto los controladores de API web como los controladores MVC heredan de la Microsoft.AspNet.Mvc.Controller
clase base.
Para enviar datos al método desde el lado del cliente, el siguiente código debería funcionar bien
//Build an object which matches the structure of our view model class
var model = {
Name: "Shyju",
Id: 123,
Tags: [{ Id: 12, Code: "C" }, { Id: 33, Code: "Swift" }]
};
$.ajax({
type: "POST",
data: JSON.stringify(model),
url: "../product/save",
contentType: "application/json"
}).done(function(res) {
console.log('res', res);
// Do something with the result :)
});
El enlace de modelo funciona para algunas propiedades, ¡pero no para todas! Por qué ?
Si no decora el parámetro del método API web con el [FromBody]
atributo
[HttpPost]
public CreateUserViewModel Save(CreateUserViewModel m)
{
return m;
}
Y envíe el modelo (objeto javascript sin procesar, no en formato JSON) sin especificar el valor de la propiedad contentType
$.ajax({
type: "POST",
data: model,
url: "../product/save"
}).done(function (res) {
console.log('res', res);
});
El enlace del modelo funcionará para las propiedades planas del modelo, no para las propiedades donde el tipo es complejo / otro tipo. En nuestro caso, Id
y las Name
propiedades se vincularán correctamente al parámetro m
, pero la Tags
propiedad será una lista vacía.
El mismo problema ocurrirá si está utilizando la versión corta, $.post
que utilizará el Tipo de contenido predeterminado al enviar la solicitud.
$.post("../product/save", model, function (res) {
//res contains the markup returned by the partial view
console.log('res', res);
});