EDIT : 31/10/2017
O mesmo código / abordagem também funcionará para o Asp.Net Core 2.0 . A principal diferença é que, no núcleo do asp.net, os controladores da API da Web e os controladores Mvc são mesclados no modelo de controlador único. Portanto, o seu tipo de retorno pode ser IActionResult
ou um de sua implementação (Ex: OkObjectResult
)
Usar
contentType:"application/json"
Você precisa usar o JSON.stringify
método para convertê-lo em string JSON ao enviá-lo,
E o fichário do modelo vinculará os dados json ao seu objeto de classe.
O código abaixo funcionará bem (testado)
$(function () {
var customer = {contact_name :"Scott",company_name:"HP"};
$.ajax({
type: "POST",
data :JSON.stringify(customer),
url: "api/Customer",
contentType: "application/json"
});
});
Resultado
contentType
A propriedade informa ao servidor que estamos enviando os dados no formato JSON. Como enviamos uma estrutura de dados JSON, a ligação do modelo ocorrerá corretamente.
Se você inspecionar os cabeçalhos da solicitação ajax, poderá ver que o Content-Type
valor está definido como application/json
.
Se você não especificar explicitamente contentType, ele usará o tipo de conteúdo padrão que é application/x-www-form-urlencoded;
Edite em novembro de 2015 para resolver outros possíveis problemas levantados nos comentários
Postando um objeto complexo
Digamos que você tenha uma classe de modelo de exibição complexa como seu parâmetro do método de ação da API da 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;}
}
e seu ponto final da API da Web é 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;
}
}
No momento da redação deste artigo, o ASP.NET MVC 6 é a versão estável mais recente e, no MVC6, os controladores de API da Web e os MVC estão herdando da Microsoft.AspNet.Mvc.Controller
classe base.
Para enviar dados para o método do lado do cliente, o código abaixo deve funcionar bem
//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 :)
});
A ligação de modelo funciona para algumas propriedades, mas não para todas! Por quê ?
Se você não decorar o parâmetro do método API da Web com o [FromBody]
atributo
[HttpPost]
public CreateUserViewModel Save(CreateUserViewModel m)
{
return m;
}
E envie o modelo (objeto javascript bruto, não no formato JSON) sem especificar o valor da propriedade contentType
$.ajax({
type: "POST",
data: model,
url: "../product/save"
}).done(function (res) {
console.log('res', res);
});
A ligação do modelo funcionará para as propriedades simples do modelo, não para as propriedades em que o tipo é complexo / outro tipo. No nosso caso, Id
e as Name
propriedades serão corretamente vinculadas ao parâmetro m
, mas a Tags
propriedade será uma lista vazia.
O mesmo problema ocorrerá se você estiver usando a versão curta, $.post
que usará o Tipo de Conteúdo padrão ao enviar a solicitação.
$.post("../product/save", model, function (res) {
//res contains the markup returned by the partial view
console.log('res', res);
});