5

我在 ASP.NET MVC 4 RC Web API 中遇到了我认为是一个奇怪的绑定问题。我有一种方法旨在接受来自客户端的发布请求。问题是调用 post 方法时没有任何参数绑定,我在 throw 行和名称上到达断点,email 都是空的。如果我在 JavaScript 中将请求的类型更改为 GET,则调用下面的 Get 函数并绑定参数。

为什么 Post 方法的参数无法绑定,我该如何解决?

send: function(evt) {
    evt.preventDefault();
    $.ajax( {
        url: '/api/person',
        data: this.model.toJSON(),
        type: "POST",
        dataType: "json",
        success: function(data) {
            console.log("Success");
        },
        error: function(data) {
            console.log("Error");
        }
    });
     }

以下是控制器动作:

public void Get(string name, string email) {
    throw new NotImplementedException();
}

public void Post(string name, string email) {
    throw new NotImplementedException();
}

笔记:

  • 我正在使用 ASP.NET MVC 4 RC Web API 的所有默认值(所以反序列化器应该是 Json.NET)
  • JS 调试器上的 Chrome 网络选项卡正确显示了 post 表单数据中的参数。
4

1 回答 1

13

与 MVC(网页)不同,默认情况下,简单参数类型不会从帖子正文绑定,而是从 URI 绑定。因此,使用您的代码原样,您需要在查询字符串中传递nameandemail参数或作为路由参数。

然而,这可以通过创建模型类型(在 MVC 白话中)并将其用于方法参数来轻松解决。实际上,如果您随后[FromUri]在 get 方法上使用,则可以将它用于两者(在您给出的情况下):

public class SomeParams {
  public string name { get; set; }
  public string email { get; set; }
}

//now an alternative way to write the Get method
public MyResult Get([FromUri] SomeParams p){
  //members are bound from the query string (more like MVC traditional binding)
  //note - as in MVC, SomeParams will need a default constructor for this to work.
}

public PostResult Post(SomeParams p){
  //'p' is bound from your JSON (assuming correct format)
  //because 'complex' types are deserialized using formatters
  //only one object can be read from the body with a formatter in Web API
  //as the request body is not buffered; unlike MVC.
}

我坚持使用方法的返回类型只是因为它们需要返回一些东西!

我真的建议阅读上面链接到的 Mike Stall 的文章(以及他的许多其他文章)。

很容易假设 Web API,因为它共享相同的范例甚至 MVC 的类名,实际上与 MVC 相同 - 但事实并非如此。我最初想知道为什么会这样(因为我自己在 MVC 之上编写了很多 REST 服务,并且发现它非常酷,一旦你编写了一些实用程序类和基类增强),但是他们已经正确看待编写 Web API 的挑战,我认为改变他们所拥有的方法可能是正确的。

然而,这确实意味着我们必须将一些我们现在可能认为理所当然的事情视为理所当然,并为 Web API 重新学习它们。

于 2012-06-22T15:17:12.163 回答