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

Nei*_*eil 8 javascript c# ajax jquery 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);
      }
    });
Run Code Online (Sandbox Code Playgroud)

我创建了一个预测的统计控制器和获取Foo参数的方法.

public class PredictedStatsController : ApiController
{
    public PredictedStats Get(Foo foo)
    {
        return statsService.GetPredictedStats(foo);
    }
}
Run Code Online (Sandbox Code Playgroud)

在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]   
Run Code Online (Sandbox Code Playgroud)

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

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

GET /api/predictedStats?foo={jsondata} HTTP/1.1
Run Code Online (Sandbox Code Playgroud)

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

谢谢尼尔


编辑:我觉得我几乎得到了以下工作

public PredictedStats Get([FromUri]Foo foo)
{
    return statsService.GetPredictedStats(foo);
}
Run Code Online (Sandbox Code Playgroud)

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


与此同时,我已经使用了具有接近相同数据的POST,只是删除了"foo =",这样就可以了.

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


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

And*_*tan 6

你快到了:)

当你使用[FromUri](你必须用于'复杂'对象,因为默认情况下Web API不会'绑定'复杂对象,它总是希望从主体反序列化它们)你不需要传入param=Uri - 你只需将值的成员作为查询字符串参数传递.那就是'member1=value&member2=value'- 在哪里member1,member2也是成员Foo.

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

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

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

  • 请注意,一个简单的`public string member1;`将不起作用,`member1`仍然是`null`.把它们变成**属性**它会正常工作. (2认同)