MODIFICA : 31/10/2017
Lo stesso codice / approccio funzionerà anche per Asp.Net Core 2.0 . La differenza principale è che, nel nucleo di asp.net, sia i controller Web API che i controller Mvc sono uniti in un unico modello di controller. Così il vostro tipo di ritorno potrebbe essere IActionResult
o una delle sue applicazione (Es: OkObjectResult
)
Uso
contentType:"application/json"
Devi utilizzare il JSON.stringify
metodo per convertirlo in stringa JSON quando lo invii,
E il raccoglitore di modelli assocerà i dati json all'oggetto classe.
Il codice seguente funzionerà bene (testato)
$(function () {
var customer = {contact_name :"Scott",company_name:"HP"};
$.ajax({
type: "POST",
data :JSON.stringify(customer),
url: "api/Customer",
contentType: "application/json"
});
});
Risultato
contentType
La proprietà dice al server che stiamo inviando i dati in formato JSON. Da quando abbiamo inviato una struttura di dati JSON, l'associazione del modello avverrà correttamente.
Se controlli le intestazioni della richiesta Ajax, puoi vedere che il Content-Type
valore è impostato come application/json
.
Se non si specifica esplicitamente contentType, verrà utilizzato il tipo di contenuto predefinito che è application/x-www-form-urlencoded;
Modifica a novembre 2015 per affrontare altre possibili questioni sollevate nei commenti
Pubblicazione di un oggetto complesso
Supponiamo che tu abbia una complessa classe del modello di vista come parametro del metodo di azione dell'API Web come questo
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 il tuo punto finale dell'API Web è simile
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 della stesura di questo documento, ASP.NET MVC 6 è l'ultima versione stabile e in MVC6, sia i controller Web API che i controller MVC ereditano dalla Microsoft.AspNet.Mvc.Controller
classe base.
Per inviare dati al metodo dal lato client, il codice seguente dovrebbe funzionare correttamente
//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 :)
});
L'associazione del modello funziona per alcune proprietà, ma non per tutte! Perché ?
Se non si decora il parametro del metodo api web con [FromBody]
attributo
[HttpPost]
public CreateUserViewModel Save(CreateUserViewModel m)
{
return m;
}
E invia il modello (oggetto javascript non elaborato, non in formato JSON) senza specificare il valore della proprietà contentType
$.ajax({
type: "POST",
data: model,
url: "../product/save"
}).done(function (res) {
console.log('res', res);
});
L'associazione del modello funzionerà per le proprietà piatte sul modello, non per quelle in cui il tipo è complesso / un altro tipo. Nel nostro caso, Id
e le Name
proprietà saranno correttamente associate al parametro m
, ma la Tags
proprietà sarà un elenco vuoto.
Lo stesso problema si verificherà se si utilizza la versione breve, $.post
che utilizzerà il tipo di contenuto predefinito quando si invia la richiesta.
$.post("../product/save", model, function (res) {
//res contains the markup returned by the partial view
console.log('res', res);
});