如何将复杂模型从客户端传递到服务器?
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'
- 其中member1
和member2
是Foo
的成员。
请注意,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 从客户端传递到服务器?