FromBody无法绑定字符串参数

41

我的问题类似于ASP.NET MVC 4 RC Web API 参数绑定问题,但我试图通过使用[FromBody]属性来解决它。

Fiddler报告以下请求(不包括用户代理字符串等不相关的部分)

PUT http://localhost:82/api/account/shoppinglistitems HTTP/1.1
Host: localhost:82
Connection: keep-alive
Content-Length: 11
Origin: http://localhost:3000
Content-Type: application/x-www-form-urlencoded
Accept: application/json, text/javascript, */*; q=0.01

query=apple

我的控制器操作是:

[HttpPut]
public ShoppingListItemWebModel CreateShoppingListItem([FromBody]string query) {
    // query is null
}

我可以将参数封装在一个复杂类型中,但那似乎是为了解决问题而采取的一种妥协方式。或者我可以将查询放在URI中,但那不符合其余API的模式。这种方式可行吗?如果可以,我的错误在哪里?


1
标题写的是POST,但问题中却写的是PUT,有点误导。 - vbullinger
Asp.Net Core 相关问题 https://dev59.com/KlwZ5IYBdhLWcg3wBcQJ - Michael Freidgeim
2个回答

45

将您的请求更改为

PUT http://localhost:82/api/account/shoppinglistitems HTTP/1.1
Host: localhost:82
Connection: keep-alive
Content-Length: 11
Origin: http://localhost:3000
Content-Type: application/x-www-form-urlencoded
Accept: application/json, text/javascript, */*; q=0.01

=apple

注意缺少 "query" 关键字。


3
怎样从正文中提取多个字符串? - Jeow Li Huan
6
不可能,你需要使用复杂类型。Mike Stall撰写了一篇很棒的博客,我推荐给任何对Web API模型绑定感兴趣的人阅读:http://blogs.msdn.com/b/jmstall/archive/2012/04/16/how-webapi-does-parameter-binding.aspx - Filip W
3
谢谢提供链接。我也发现如果你不想创建一个模型,你可以使用 Request.Content.ReadAsStringAsync().Result来解析内容。 - nullable
感谢 @Kurt 指出这种方法。在多次尝试后,这是我案例中唯一有用的解决方案(想要将 JSON 值作为字符串发布到服务器)。 - Felipe Castro
1
我知道这是一个旧的帖子,但是由于我遇到了同样的问题,而且解决方案非常反直觉,所以我想知道您是否知道为什么会出现这种情况?您能否指向一些相关文章? - Joanna Derks
显示剩余2条评论

23

如果您使用AngularJS而不是jQuery,您可能要选择以下替代方案,因为AngularJS默认使用内容类型application/json

PUT http://localhost:82/api/account/shoppinglistitems HTTP/1.1
Host: localhost:82
Connection: keep-alive
Content-Length: 7
Origin: http://localhost:3000
Content-Type: application/json
Accept: application/json, text/javascript, */*; q=0.01

'apple'

注意值被包含在引号(单引号或双引号)中。


11
在 Angular 中,您可以使用 angular.toJson 对有效负载进行编码以获得引号包装。 - Richard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接