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

Posted

技术标签:

【中文标题】如何将复杂模型从客户端传递到服务器?【英文标题】:How to pass complex model from client to server? 【发布时间】:2012-07-31 05:32:52 【问题描述】:

我有一些数据“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 可能是唯一明智的选择

【问题讨论】:

【参考方案1】:

你快到了:)

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

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

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

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

【讨论】:

谢谢,虽然我用[FromUri] 装饰了一个“复杂对象”参数,但我一直在摸不着头脑。我试图传递 json 例如?param=Name: Foo 这不起作用,我不得不将其更改为 ?Name=Foo 如你所说。请注意,如果您有多个 [FromUri] 复杂对象参数,则需要确保它们没有同名的属性 - 否则您最终会为两个实例分配相同的属性值。 请注意,简单的public string member1; 将不起作用,member1 仍将是null。把它们变成properties就可以了。 关于他们必须是财产...为什么我 4 小时前没有读到这篇文章。谈论感觉愚蠢,感谢托马斯这个简单但非常完美的评论。 别忘了做 /?或使用?就在您的 api 路由之后,因为它不起作用,例如url:port/apiroute/?'member1=value&member2=value' 会起作用......如果你忘记了?它不会...

以上是关于如何将复杂模型从客户端传递到服务器?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ASP.NET Core Razor 页面中绑定复杂列表

如何将数据从可解码模型传递或实现到 ViewController?

如何将 Firebase Auth Token 从客户端传递到服务器?

如何使用ajax请求将印地语字体从客户端传递到服务器

如何将 Windows 身份验证凭据从客户端传递到 Web API 服务

将令牌从服务器传递到客户端并以安全方式存储