如何通过JSON POST数据的Web API方法为研究对象 [英] How to pass json POST data to Web API method as object

查看:360
本文介绍了如何通过JSON POST数据的Web API方法为研究对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

ASP.NET的Web MVC4 API应用程序定义了POST方法来保存客户。
客户在POST请求主体JSON格式传递。
在POST方法客户参数包含的属性空值。

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

如果可能的内容类型:应用程序/ x-WWW的形式urlen codeD应该使用,因为我不知道如何去改变它在JavaScript方法,帖子的形式

控制器:

 公共类CustomersController:ApiController {  公共对象后([FromBody]客户的客户)
        {
            返回Request.CreateResponse(的HTTPStatus code.OK,
            新
            {
                客户=客户
            });
        }
    }
}公共类客户
    {
        公共字符串COMPANY_NAME {搞定;组; }
        公共字符串CONTACT_NAME {搞定;组; }
     }

请求:

  POST HTTP://本地主机:52216 / API /客户HTTP / 1.1
接受:应用/ JSON,文本/ javascript中,* / *; Q = 0.01
的X请求 - 由于:XMLHtt prequest
内容类型:应用程序/ x-WWW的形式urlen codeD;字符集= UTF-8{CONTACT_NAME:sdfsd,COMPANY_NAME:ssssd}


解决方案

使用

 的contentType:应用/ JSON

您需要使用 JSON.stringify 方法将其转换成JSON格式,当你发送,

和模型绑定将JSON数据绑定到你的类的对象。

下面code将正常工作(测试)

  $(函数(){
    VAR的客户= {CONTACT_NAME:斯科特,COMPANY_NAME:惠普};
    $阿贾克斯({
        键入:POST,
        数据:JSON.stringify(客户),
        网址:API /客户,
        的contentType:应用/ JSON
    });
});

结果

的contentType 属性告诉我们发送JSON格式的数据的服务器。因为我们派出了JSON数据结构,模型绑定将正常出现。

如果您检查Ajax请求的头,你可以看到内容类型值设置为应用程序/ JSON

如果你没有明确指定的contentType,它将使用其默认的内容类型应用程序/ x-WWW的形式urlen codeD;


在2015年11月编辑,以解决意见中提出的其他可能的问题

发布一个复杂的对象

假设你有一个复杂的视图模型类像这样

您的Web API操作方法参数

 公共类CreateUserViewModel
{
   公众诠释标识{集;获取;}
   公共字符串名称{集;获取;}
   公开名单< TagViewModel>标签{集;获取;}
}
公共类TagViewModel
{
  公众诠释标识{集;获取;}
  公共字符串code {集;获取;}
}

和您的Web API终点是像

 公共类ProductController的:控制器
{
    [HttpPost]
    公共CreateUserViewMode保存([FromBody] CreateUserViewModel米)
    {
        //我只是返回贴模式,因为它是。
        //你可以做其他的东西,并返回不同的反应。
        //例如:missileService.LaunchMissile(M);
        返回米;
    }
}

在写这篇文章的时候,ASP.NET MVC 6是最新的稳定版本,并在MVC6,这两个Web API控制器和MVC控制器从 Microsoft.AspNet.Mvc.Controller继承基类。

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

  //构建这我们认为模型类的结构相匹配的对象
VAR模型= {
    产品名称:Shyju
    编号:123,
    标签:[{ID:12,code:C},{ID:33,code:雨燕}]
};$阿贾克斯({
    键入:POST,
    数据:JSON.stringify(模型),
    网址:../product/save
    的contentType:应用/ JSON
})。完成(功能(RES){
    的console.log('资源',RES);
    //做一些事情的结果:)
});

模型结合一些性质的作品,但不是全部!为什么呢?

如果你不装饰与Web API方法参数 [FromBody] 属性

  [HttpPost]
公共CreateUserViewModel保存(CreateUserViewModel米)
{
    返回米;
}

和不指定contentType属性值发送(不以JSON格式的原始JavaScript对象)模型

  $。阿贾克斯({
    键入:POST,
    数据:模型,
    网址:../product/save
})。完成(功能(RES){
     的console.log('资源',RES);
});

模型结合将为在模型上,而不是其中类型是复杂/另一种类型的属性的平坦性质工作。在我们的例子中,编号名称属性将会被正确地绑定到参数 M ,但标签属性将成为空表。

如果您使用的是短版, $。POST 发送请求时将使用默认的Content-Type将出现同样的问题。

  $。员额(../产品/保存,型号,功能(RES){
    //资源包含了由局部视图返回的标记
    的console.log('资源',RES);
});

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 ?

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.

Controller:

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

Request:

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

解决方案

Use

contentType:"application/json"

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

And the model binding 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"
    });
});

Result

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.

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

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


Edit on Nov 2015 to address other possible issues raised in comments

Posting a complex object

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

and your web api end point is like

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.

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

[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

$.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.

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天全站免登陆