如何将json POST数据作为对象传递给Web API方法?
ASP.NET MVC4 Web API应用程序定义了保存客户的post方法。 客户在POST请求正文中以json格式传递。 post方法中的Customer参数包含属性的空值。
如何解决这个问题,使发布的数据作为客户对象传递?
如果可能的话,Content-Type:application / x-www-form-urlencoded应该被使用,因为我不知道如何在javascript方法中改变它的发布形式。
控制器:
public class CustomersController : ApiController {
public object Post([FromBody] Customer customer)
{
return Request.CreateResponse(HttpStatusCode.OK,
new
{
customer = customer
});
}
}
}
public class Customer
{
public string company_name { get; set; }
public string contact_name { get; set; }
}
请求:
POST http://localhost:52216/api/customers HTTP/1.1
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
{"contact_name":"sdfsd","company_name":"ssssd"}
编辑 :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 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;
}
}
在写这篇文章的时候,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;
}
并发送模型(原始javascript对象,不是JSON格式),而不指定contentType属性值
$.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);
});
在webapi中使用POST可能会很棘手! 想添加到已经正确的答案..
将重点放在POST上,因为处理GET是微不足道的。 我不认为很多人会用webapis来解决GET问题。 无论如何..
如果你的问题是 - 在MVC Web Api中,如何 - 使用通用HTTP动词之外的自定义动作方法名称? - 执行多个帖子? - 发布多种简单类型? - 通过jQuery发布复杂类型?
那么以下解决方案可能有所帮助
首先,要在Web API中使用自定义操作方法,请添加一个web api路由:
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}");
}
然后你可以创建如下的操作方法:
[HttpPost]
public string TestMethod([FromBody]string value)
{
return "Hello from http post web api controller: " + value;
}
现在,从您的浏览器控制台中触发以下jQuery
$.ajax({
type: 'POST',
url: 'http://localhost:33649/api/TestApi/TestMethod',
data: {'':'hello'},
contentType: 'application/x-www-form-urlencoded',
dataType: 'json',
success: function(data){ console.log(data) }
});
其次,要执行多个帖子 ,很简单,创建多个操作方法并用[HttpPost] attrib装饰。 使用[ActionName(“MyAction”)]来分配自定义名称等。将在下面的第四点来到jQuery
第三,首先,在单个动作中发布多个SIMPLE类型是不可能的。 此外,还有一种特殊的格式来发布甚至一个简单的类型 (除了在查询字符串或REST风格中传递参数)。 这是让我用Rest客户端(如Fiddler和Chrome的高级REST客户端扩展)猛击我的头并在最终浏览网页近5个小时的时候,以下URL被证明是有帮助的。 将引用链接的相关内容可能会失效!
Content-Type: application/x-www-form-urlencoded
in the request header and add a = before the JSON statement:
={"Name":"Turbo Tina","Email":"na@Turbo.Tina"}
PS:注意到特有的语法?
http://forums.asp.net/t/1883467.aspx?The+received+value+is+null+when+I+try+to+Post+to+my+Web+Api
无论如何,让我们来看看这个故事。 继续:
第四,通过jQuery 发布复杂类型 ,当然,$ .ajax()会立即出现在角色中:
让我们说动作方法接受一个具有id和名字的Person对象。 所以,从javascript:
var person = { PersonId:1, Name:"James" }
$.ajax({
type: 'POST',
url: 'http://mydomain/api/TestApi/TestMethod',
data: JSON.stringify(person),
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function(data){ console.log(data) }
});
行动将如下所示:
[HttpPost]
public string TestMethod(Person person)
{
return "Hello from http post web api controller: " + person.Name;
}
以上所有,为我工作! 干杯!
我刚刚一直在玩这个,发现了一个相当奇怪的结果。 假设你在C#中的类中拥有公共属性,如下所示:
public class Customer
{
public string contact_name;
public string company_name;
}
那么你必须按照Shyju的建议去做JSON.stringify技巧,并且像这样调用它:
var customer = {contact_name :"Scott",company_name:"HP"};
$.ajax({
type: "POST",
data :JSON.stringify(customer),
url: "api/Customer",
contentType: "application/json"
});
但是,如果你像这样在你的类上定义getter和setter:
public class Customer
{
public string contact_name { get; set; }
public string company_name { get; set; }
}
那么你可以更简单地调用它:
$.ajax({
type: "POST",
data :customer,
url: "api/Customer"
});
这使用HTTP标头:
Content-Type:application/x-www-form-urlencoded
我不太确定这里发生了什么,但它看起来像框架中的一个错误(特征?)。 据推测,不同的绑定方法正在调用不同的“适配器”,而application / json的适配器可以与公共属性一起工作,而编码数据的适配器则不适用。
我不知道哪一个会被认为是最佳实践。
链接地址: http://www.djcxy.com/p/3469.html上一篇: How to pass json POST data to Web API method as an object?