【问题标题】:ASP.NET MVC 4 RC Web API Parameter Binding IssueASP.NET MVC 4 RC Web API 参数绑定问题
【发布时间】:2012-06-24 21:29:15
【问题描述】:

我在 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 表单数据中的参数。

【问题讨论】:

    标签: c# .net asp.net-mvc-4 asp.net-web-api


    【解决方案1】:

    不像MVC(网页),简单的参数类型will not, by default, bind from the post body but instead from the URI。因此,使用您的代码原样,您需要在查询字符串中或作为路由参数传递 nameemail 参数。

    但是,这可以通过创建模型类型(在 MVC 白话中)并将其用于方法参数来轻松解决。事实上,如果你在 get 方法上使用[FromUri],那么你可以同时使用它(在你给出的情况下):

    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 重新学习它们。

    【讨论】:

    • 我的get参数不是无效的,事实上它甚至不存在。我可能不清楚,但这只是为了说明该功能适用​​于 GET 而不适用于 POST。
    • 好吧 - 好吧,那很好:)。不过,简而言之,如果您要从请求的主体中绑定多个参数,那么基本上最简单的事情就是编写一个简单的模型类型,如我所示。
    • 感谢 Mike Stall 文章链接,它对正在发生的事情提供了非常丰富的信息。我刚刚假设 Web API 使用与 MVC 完全相同的绑定策略。创建一个自定义类来接收参数就像一个魅力,我不是那个解决方案的粉丝,但我不知道为什么,所以我可能只是很固执。 :) 无论如何,这是我将使用的解决方案。谢谢! :)
    • 完全正确 - 我也是一样,发现自己摸了一会儿头。我确实认为他们采取了正确的方法。这是无法多次读取请求正文所带来的挑战,因为他们希望通过不缓冲来最大化性能。说得通。无论如何 - 可以创建一个自定义调用程序(或堆栈中的任何位置,我现在忘记了)以从方法签名动态生成打包参数类 - 从而以您想要的方式自动强制从主体绑定。我可能会对此进行调查,实际上......
    • 有趣的是,据我所知,多个简单类型绑定在 MVC 4 beta ApiControllers 中工作!因此,这似乎在游戏后期发生了变化……很遗憾,因为我们的产品应用程序之一在某些地方依赖于它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-28
    • 1970-01-01
    • 1970-01-01
    • 2013-01-24
    • 1970-01-01
    • 2012-10-11
    • 1970-01-01
    相关资源
    最近更新 更多