如何将 json POST 数据作为对象传递给 Web API 方法? [英] How to pass json POST data to Web API method as an object?

查看:25
本文介绍了如何将 json POST 数据作为对象传递给 Web API 方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

ASP.NET MVC4 Web API 应用程序定义了 post 方法来保存客户.客户在 POST 请求正文中以 json 格式传递.post方法中的客户参数包含属性的空值.

ASP.NET MVC4 Web API application defines post method to save customer. Customer is passed in json format in POST request body. Customer parameter in post method contains null values for properties.

如何解决这个问题,以便发布的数据将作为客户对象传递?

How to fix this so that posted data will passed as customer object ?

如果可能,应该使用 Content-Type: application/x-www-form-urlencoded 因为我不知道如何在发布表单的 javascript 方法中更改它.

If possible Content-Type: application/x-www-form-urlencoded should used since I dont know how to change it in javascript method which posts form.

控制器:

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

推荐答案

EDIT : 31/10/2017

EDIT : 31/10/2017

相同的代码/方法也适用于 Asp.Net Core 2.0.主要区别在于,在 asp.net core 中,web api 控制器和 Mvc 控制器合并在一起为单个控制器模型.所以你的返回类型可能是 IActionResult 或者它的实现之一(例如:OkObjectResult)

The same code/approach will work for Asp.Net Core 2.0 as well. The major difference is, In asp.net core, both web api controllers and Mvc controllers are merged together to single controller model. So your return type might be IActionResult or one of it's implementation (Ex :OkObjectResult)

使用

contentType:"application/json"

发送时需要使用JSON.stringify方法将其转换为JSON字符串,

You need to use JSON.stringify method to convert it to JSON string when you send it,

模型绑定器会将 json 数据绑定到您的类对象.

And the model binder will bind the json data to your class object.

下面的代码可以正常工作(已测试)

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

结果

contentType 属性告诉服务器我们正在以 JSON 格式发送数据.由于我们发送的是 JSON 数据结构,因此模型绑定会正确发生.

contentType property tells the server that we are sending the data in JSON format. Since we sent a JSON data structure,model binding will happen properly.

如果您检查 ajax 请求的标头,您可以看到 Content-Type 值设置为 application/json.

If you inspect the ajax request's headers, you can see that the Content-Type value is set as application/json.

如果你没有明确指定 contentType,它将使用默认的内容类型 application/x-www-form-urlencoded;

If you do not specify contentType explicitly, It will use the default content type which is application/x-www-form-urlencoded;

在 2015 年 11 月进行编辑以解决评论中提出的其他可能的问题

假设您有一个复杂的视图模型类作为您的 web api 操作方法参数,如下所示

Let's say you have a complex view model class as your web api action method parameter like this

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 端点就像

and your web api end point is like

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 基类.

要从客户端向方法发送数据,下面的代码应该可以正常工作

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

模型绑定适用于某些属性,但不是全部!为什么?

如果没有用[FromBody]属性修饰web api方法参数

Model binding works for some properties, but not all ! Why ?

If you do not decorate the web api method parameter with [FromBody] attribute

[HttpPost]
public CreateUserViewModel Save(CreateUserViewModel m)
{
    return m;
}

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

And send the model(raw javascript object, not in JSON format) without specifying the contentType property value

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

模型绑定将适用于模型上的平面属性,而不是类型为复杂/其他类型的属性.在我们的例子中,IdName 属性将正确绑定到参数 m,但 Tags 属性将是一个空列表.

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.

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

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("../product/save", model, function (res) {
    //res contains the markup returned by the partial view
    console.log('res', res);
});

这篇关于如何将 json POST 数据作为对象传递给 Web API 方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆