编辑:31/10/2017
同样的代码/方法也适用于Asp.Net Core 2.0。主要区别在于,在asp.net核心中,Web api控制器和Mvc控制器都合并在一起成为单个控制器模型。所以,你的返回类型可能是IActionResult
或它的实现之一(例如:OkObjectResult
)
采用
contentType:"application/json"
JSON.stringify
发送时,您需要使用方法将其转换为JSON字符串,
然后,模型绑定器会将json数据绑定到您的类对象。
下面的代码可以正常工作(经过测试)
$(function () {
var customer = {contact_name :"Scott",company_name:"HP"};
$.ajax({
type: "POST",
data :JSON.stringify(customer),
url: "api/Customer",
contentType: "application/json"
});
});
结果
contentType
属性告诉服务器我们正在以JSON格式发送数据。由于我们发送了JSON数据结构,因此模型绑定将正确进行。
如果检查ajax请求的标头,则可以看到该Content-Type
值设置为application/json
。
如果未明确指定contentType,它将使用默认的内容类型,即 application/x-www-form-urlencoded;
编辑于2015年11月以解决评论中提出的其他可能问题
发布复杂对象
假设您有一个复杂的视图模型类作为您的Web api操作方法参数,如下所示
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;}
}
和您的Web API端点就像
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;
}
}
在撰写本文时,ASP.NET MVC 6是最新的稳定版本,并且在MVC6中,Web api控制器和MVC控制器都从Microsoft.AspNet.Mvc.Controller
基类继承。
要将数据从客户端发送到方法,以下代码应该可以正常工作
//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 :)
});
模型绑定适用于某些属性,但并非全部!为什么呢
如果您不使用[FromBody]
属性修饰Web api方法参数
[HttpPost]
public CreateUserViewModel Save(CreateUserViewModel m)
{
return m;
}
并在不指定contentType属性值的情况下发送模型(原始javascript对象,非JSON格式)
$.ajax({
type: "POST",
data: model,
url: "../product/save"
}).done(function (res) {
console.log('res', res);
});
模型绑定将对模型的平面属性起作用,不适用于类型为复杂/另一种类型的属性。在我们的示例中,Id
和Name
属性将正确绑定到参数m
,但是Tags
属性将是一个空列表。
如果您使用的是简短版本,则会发生相同的问题,该简短版本$.post
在发送请求时将使用默认的Content-Type。
$.post("../product/save", model, function (res) {
//res contains the markup returned by the partial view
console.log('res', res);
});