EDIT : 31/10/2017
(编辑 :31/10/2017)
The same code/approach will work for Asp.Net Core 2.0 as well.
(相同的代码/方法也适用于Asp.Net Core 2.0 。)
The major difference is, In asp.net core, both web api controllers and Mvc controllers are merged together to single controller model.(主要区别在于,在asp.net核心中,web api控制器和Mvc控制器都合并到单个控制器模型中。)
So your return type might be IActionResult
or one of it's implementation (Ex : OkObjectResult
)(所以你的返回类型可能是IActionResult
或其中一个实现(例如: OkObjectResult
))
Use
(使用)
contentType:"application/json"
You need to use JSON.stringify
method to convert it to JSON string when you send it,
(发送时需要使用JSON.stringify
方法将其转换为JSON字符串,)
And the model binder will bind the json data to your class object.
(模型绑定器将json数据绑定到您的类对象。)
The below code will work fine (tested)
(以下代码将正常工作(测试))
$(function () {
var customer = {contact_name :"Scott",company_name:"HP"};
$.ajax({
type: "POST",
data :JSON.stringify(customer),
url: "api/Customer",
contentType: "application/json"
});
});
Result
(结果)
contentType
property tells the server that we are sending the data in JSON format.
(contentType
属性告诉服务器我们正在以JSON格式发送数据。)
Since we sent a JSON data structure,model binding will happen properly.(由于我们发送了JSON数据结构,因此模型绑定将正确发生。)
If you inspect the ajax request's headers, you can see that the Content-Type
value is set as application/json
.
(如果检查ajax请求的标头,则可以看到Content-Type
值设置为application/json
。)
If you do not specify contentType explicitly, It will use the default content type which is application/x-www-form-urlencoded;
(如果您没有明确指定contentType,它将使用默认的内容类型,即application/x-www-form-urlencoded;
)
Edit on Nov 2015 to address other possible issues raised in comments
(2015年11月编辑,以解决评论中提出的其他可能问题)
Posting a complex object(发布复杂对象)
Let's say you have a complex view model class as your web api action method parameter like this
(假设你有一个复杂的视图模型类作为你的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;}
}
and your web api end point is like
(和你的web api终点就像)
public class ProductController : Controller
{
[HttpPost]
public CreateUserViewMode 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;
}
}
At the time of this writing, ASP.NET MVC 6 is the latest stable version and in MVC6, Both Web api controllers and MVC controllers are inheriting from Microsoft.AspNet.Mvc.Controller
base class.
(在撰写本文时,ASP.NET MVC 6是最新的稳定版本,在MVC6中,Web api控制器和MVC控制器都继承自Microsoft.AspNet.Mvc.Controller
基类。)
To send data to the method from client side, the below code should work fine
(要从客户端向方法发送数据,下面的代码应该可以正常工作)
//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 :)
});
Model binding works for some properties, but not all !(模型绑定适用于某些属性,但不是全部!) Why ?(为什么?)
If you do not decorate the web api method parameter with [FromBody]
attribute
(如果不使用[FromBody]
属性修饰web api方法参数)
[HttpPost]
public CreateUserViewModel Save(CreateUserViewModel m)
{
return m;
}
And send the model(raw javascript object, not in JSON format) without specifying the contentType property value
(并且在不指定contentType属性值的情况下发送模型(原始javascript对象,而不是JSON格式))
$.ajax({
type: "POST",
data: model,
url: "../product/save"
}).done(function (res) {
console.log('res', res);
});
Model binding will work for the flat properties on the model, not the properties where the type is complex/another type.
(模型绑定适用于模型上的平面属性,而不适用于类型复杂/其他类型的属性。)
In our case, Id
and Name
properties will be properly bound to the parameter m
, But the Tags
property will be an empty list.(在我们的例子中, Id
和Name
属性将正确绑定到参数m
,但Tags
属性将是一个空列表。)
The same problem will occur if you are using the short version, $.post
which will use the default Content-Type when sending the request.
(如果您使用的是简短版本$.post
,在发送请求时将使用默认的Content-Type,则会出现同样的问题。)
$.post("../product/save", model, function (res) {
//res contains the markup returned by the partial view
console.log('res', res);
});