如何将复杂模型从客户端传递到服务器?

时间:2012-08-02 09:00:52

标签: c# javascript jquery ajax asp.net-web-api

我有一些数据“Foo”,我想从浏览器传递到服务器,并根据foo中包含的信息检索预测的统计数据。

$.ajax({
      type: 'GET',
      url: "/api/predictedStats/",
      data: "foo=" + ko.toJSON(foo, fooProperties),
      contentType: 'application/json; charset=utf-8',
      dataType: 'json',
      success: function(data) {
        return _this.viewModel.setPredictedStats(data);
      },
      error: function(jqXHR, statusText, errorText) {
        return _this.viewModel.setErrorValues(jqXHR, errorText);
      }
    });

我创建了一个预测的统计控制器,并使用Foo的参数获取方法。

public class PredictedStatsController : ApiController
{
    public PredictedStats Get(Foo foo)
    {
        return statsService.GetPredictedStats(foo);
    }
}

在Get方法上粘贴断点我看到Foo对象始终为null。 webapi跟踪日志记录中没有抛出任何错误,只有以下几行。

WEBAPI: opr[FormatterParameterBinding] opn[ExecuteBindingAsync] msg[Binding parameter 'foo'] status[0]  
WEBAPI: opr[JsonMediaTypeFormatter] opn[ReadFromStreamAsync] msg[Type='foo', content-type='application/json; charset=utf-8'] status[0]  
WEBAPI: opr[JsonMediaTypeFormatter] opn[ReadFromStreamAsync] msg[Value read='null'] status[0]   

我没有问题通过帖子将数据发送到Foo控制器以在服务器上创建Foo对象,所以我可以说json创建的clientide没有任何问题。

在fiddler中查看得到的Get看起来像以下jsondata是对象foo。

GET /api/predictedStats?foo={jsondata} HTTP/1.1

这甚至可能还是我认为这一切都错了?

由于 尼尔


编辑: 我觉得我几乎可以使用以下

public PredictedStats Get([FromUri]Foo foo)
{
    return statsService.GetPredictedStats(foo);
}

对象foo恢复正常但没有正确填充Foo的属性。


与此同时,我使用了几乎相同数据的POST,只是删掉了“foo =”,这样就可以了。

我不确定在这种情况下是应该使用POST还是GET,但这很有趣。


我也发现这个http://bugs.jquery.com/ticket/8961似乎暗示你不能用jquery将一个主体附加到GET请求,所以POST可能是唯一明智的选择

1 个答案:

答案 0 :(得分:6)

你几乎到了那里:)

当你使用[FromUri]时(你必须使用'复杂'对象,因为默认情况下Web API不会'绑定'复杂对象,它总是希望从身体反序列化它们)你没有需要在Uri中传递param= - 您只需将值的成员作为查询字符串参数传递。这是'member1=value&member2=value' - 其中member1member2Foo的成员。

注意jQuery中没有'bug' - 虽然HTTP规范并没有禁止请求体,但浏览器很可能(如果是这样的话,jQuery就无法发送它),而且它更多可能是服务器永远不会读它。这只是不被接受的做法。它还有一些有趣的缓存问题,因为浏览器不会缓存POST,PUT,DELETE等,但如果响应头不禁止它,它将缓存GET - 这可能会产生严重的副作用客户端应用程序。我建议您查看此SO:HTTP GET with request body以获取有关此主题的更多信息和一些有用的链接。

同样,当使用jQuery时 - 您也不需要将对象转换为JSON - 只需在选项的data成员中传递javascript对象,jQuery就会将其转换为正确的格式。

或者应该是这样,Web API理解jQuery传递它的格式。