我正在使用C#编写一个简单的WebApi程序。 (我非常了解MVC,但我是WebApi的新手。)它包含一个Vendors控制器(VendorsController.cs),它包含一个“getvendor”动作,如下面的代码示例所示:
[RoutePrefix("api/vendors")]
public class VendorsController : ApiController
{
[Route("getvendor"), HttpPost]
public TAPUser GetVendor([FromBody] string username)
{
Int32 userid = -1;
...
路由配置如下:
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { action = RouteParameter.Optional, id = RouteParameter.Optional
);
我正在使用Fiddler来测试程序。首先,我在没有[FromBody]的情况下运行上面的代码并使用Fiddler在url中发送带有用户名的POST请求,如下所示: http://localhost:60060/api/vendors/getvendor?username=tapuser
这很好用。 tapuser作为参数传递给GetVendor,并且操作返回了预期的结果。
接下来,我添加了[FromBody]并将username=tapuser
放入请求正文中。这次,当我发送请求时,tapuser
没有传递给操作。 GetVendor()
的论点是null
。我在请求主体上尝试过变体,例如{ "username": "tapuser" }
,但它没有帮助。我也尝试过以各种方式更改路线,例如将routeTemplate
更改为"api/{controller}/{action}/{id}"
。这也没有帮助。我确定我错过了很简单的东西,但我只是看不到它。
答案 0 :(得分:16)
答案 1 :(得分:1)
现在我做了一些调试,并且能够重新创建你遇到的问题。
我最终能够通过执行以下操作获取数据:
首先,我创建了一个类作为有效负载的容器。
public class body {
public string username { get; set; }
}
并更新了匹配
的操作[Route("getvendor"), HttpPost]
public TAPUser GetVendor([FromBody] body payload) {...}
然后使用fiddler我将请求编写到端点进行测试。
POST http://localhost:60060/api/vendors/getvendor HTTP/1.1
User-Agent: Fiddler
Host: localhost:60060
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Content-Length: 16
username=tapuser
当我的断点被击中时,身体/有效负载填充了用户名为tapuser。
<强>更新强>
现在虽然上述工作有效,但我并不完全确定它解决了你的问题所以我做了一些谷歌搜索并遇到了这个
Parameter Binding in ASP.NET Web API
使用[FromBody]
要强制Web API从请求正文中读取简单类型,请添加 [FromBody]属性为参数:
public HttpResponseMessage Post([FromBody] string name) { ... }
在此示例中,Web API将使用媒体类型格式化程序来读取 请求正文中的name值。这是一个示例客户端 请求。
POST http://localhost:5076/api/values HTTP/1.1
User-Agent: Fiddler
Host: localhost:5076
Content-Type: application/json
Content-Length: 7
"Alice"
当参数具有[FromBody]时,Web API使用Content-Type标头 选择格式化程序。在此示例中,内容类型为 &#34;应用/ JSON&#34;并且请求正文是一个原始的JSON字符串(不是 JSON对象)。
最多允许一个参数从邮件正文中读取。所以 这不起作用:
// Caution: Will not work!
public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }
此规则的原因是请求正文可能存储在 非缓冲流只能读取一次。
当我恢复原始更改并按照示例运行时,它按预期工作。
希望这有帮助。
答案 2 :(得分:1)
我发现如果我把“tapuser”放在那里。在请求正文中,使用单引号或双引号,它可以工作。报价似乎就是答案。如果我在引号内放置除tapuser之外的任何内容,则整个事件将作为参数传递。例如,&#39; {username = tapuser}&#39;将以{username = tapuser}传递。感谢大家的意见。