如何将json POST数据作为对象传递给Web API方法?

22 浏览
0 Comments

如何将json POST数据作为对象传递给Web API方法?

ASP.NET MVC4 Web API应用程序定义了一个POST方法来保存客户信息。

客户信息以JSON格式在POST请求体中传递。

POST方法中的客户参数包含属性的空值。

如何修复此问题以便以客户对象的形式传递发布的数据?

如果可能的话,应使用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"}

admin 更改状态以发布 2023年5月21日
0
0 Comments

在web api中处理POST请求可能有一些棘手的问题!想要添加到已经正确的答案中...

专注于POST,因为处理GET很简单。我不认为有很多人会搜索解决与webapi的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]属性进行装饰。使用[ActionName("MyAction")]来指定自定义名称等。在下面的第四点中将涉及到jQuery

第三,首先,无法在单个动作中发布多个简单类型。此外,甚至要发布单个简单类型也需要特殊格式(除了通过查询字符串或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"}

注意到不寻常的语法吗?

http://forums.asp.net/t/1883467.aspx?The+received+value+is+null+when+I+try+to+Post+to+my+Web+Api

无论如何,让我们继续下去:

第四,通过jQuery发布复杂类型,当然,$.ajax()会迅速发挥作用:

假设操作方法接受一个Person对象,该对象具有一个id和一个name。所以,从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;
}

上述全部对我起作用!!干杯!

0
0 Comments

编辑:2017年10月31日

同样的代码/方法也适用于Asp.Net Core 2.0。主要区别是,在asp.net core中,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"
    });
});

结果

enter image description here

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 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;
}

并发送模型(原始JavaScript对象,而不是JSON格式),而不指定contentType属性值

$.ajax({
    type: "POST",
    data: model,
    url: "../product/save"
}).done(function (res) {
     console.log('res', res);
});

模型绑定将对模型上的平展属性起作用,而不是类型是复杂/另一个类型的属性。在我们的情况下,IdName属性将正确绑定到参数m,但Tags属性将是一个空列表。

如果您使用$.post的简短版本发送请求时,也会出现同样的问题,这将使用默认的Content-Type。

$.post("../product/save", model, function (res) {
    //res contains the markup returned by the partial view
    console.log('res', res);
});

0