8

我有一些数据“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 对象始终为空。仅以下几行的 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 客户端没有任何问题。

在 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 可能是唯一明智的选择

4

1 回答 1

6

你几乎到了那里:)

当您使用时[FromUri](您必须将其用于“复杂”对象,因为默认情况下 Web API 不会“绑定”复杂对象,它总是希望从正文中反序列化它们)您不需要传入param=Uri - 您只需将值的成员作为查询字符串参数传递。那就是'member1=value&member2=value'- wheremember1member2are 的成员Foo

请注意,jQuery 中没有“错误”——虽然 HTTP 规范不禁止请求正文,但浏览器很可能会这样做(如果是这种情况,jQuery 无法发送它),而且很有可能是无论如何,服务器永远不会读取它。这只是不被接受的做法。它还可能存在缓存的有趣问题,因为浏览器不会缓存 POST、PUT、DELETE 等,但如果响应标头不禁止它会缓存 GET - 这可能会产生严重的副作用客户端应用程序。我建议你看一下这个 SO:HTTP GET with request body以获得更多信息和一些关于这个主题的有用链接。

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

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

于 2012-08-02T21:49:01.527 回答