为什么ModelBinding不能与FormData一起使用但与RequestPayload一起使用?

时间:2014-01-29 12:53:43

标签: javascript ajax asp.net-web-api

我一直在使用Web API,发现了一个我无法理解的有趣观察。

控制器:

public class UserController: ApiController
{
   public void Post(MyViewModel data)
   {
      //data is null here if pass in FormData but available if its sent through Request Payload
   }
}

视图模型

public class MyViewModel{
        public long SenderId { get; set; }
        public string MessageText { get; set; }      
        public long[] Receivers { get; set; }
}

JS无效

var usr = {};
usr.SenderId = "10";
usr.MessageText = "test message";
usr.Receivers = new Array();
usr.Receivers.push("4");
usr.Receivers.push("5");
usr.Receivers.push("6");

$.ajax(
{ 
    url: '/api/User',
    type: 'POST',
    data: JSON.stringify(usr),
    success: function(response) { debugger; },
    error: function(error) {debugger;}
});

正在运作的JS

var usr = {};
usr.SenderId = "10";
usr.MessageText = "test message";
usr.Receivers = new Array();
usr.Receivers.push("4");
usr.Receivers.push("5");
usr.Receivers.push("6");

$.post( "/api/User", usr)
.done(function( data ) {
debugger;
});

因此,如果我使用$.ajaxtypecontentType等许多其他配置传递accept,它仍然无法正确绑定模型,以防万一$.post它有效。

有人可以解释为什么?

1 个答案:

答案 0 :(得分:0)

尝试使用$.ajax(例如使用您选择的F12工具的Fiddler)查看POST的内容。很可能jQuery将数据作为URL编码的字符串传递而不是JSON文字。

要解决此问题,请尝试将dataTypecontentType参数一起指定。另外,我认为您不需要JSON.stringify,只需传递您正在创建的JSON文字:

$.ajax({
  data: usr,
  dataType: 'json',
  contentType: 'application/json',
  /* The rest of your configuration. */
});

这是我们在其中一个项目中使用的TypeScript方法(ko.toJSON返回一个表示作为方法参数传递的JSON文字的字符串):

public static callApi(url: string, type?: string, data?: any): RSVP.Promise {
    return new RSVP.Promise((resolve, reject) => {
        $.ajax('/api/' + url, {
            type: type || 'get',
            data: data != null ? ko.toJSON(data) : null,
            dataType: 'json',
            contentType: 'application/json; charset=utf-8',
            success: () => {
                resolve.apply(this, arguments);
            },
            error: () => {
                reject.apply(this, arguments);
            }
        });
    });
}

希望这有帮助。

相关问题