【问题标题】:Using Fiddler to send a POST request to WebApi使用 Fiddler 向 WebApi 发送 POST 请求
【发布时间】:2016-06-13 06:58:21
【问题描述】:

我正在使用 C# 编写一个简单的 WebApi 程序。 (我非常了解 MVC,但我是 WebApi 的新手。)它包含一个供应商控制器 (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}"。那也没有帮助。我确定我遗漏了一些非常简单的东西,但我只是没有看到它。

【问题讨论】:

  • 您确定在请求标头中将内容类型指定为 application/json 吗?如果仍未解决,您能否分享您的提琴手屏幕截图/代码。
  • 旁注:来自 Fiddler 的请求的原始视图作为文本比图像更好
  • POST localhost:60060/api/vendors/getvendor HTTP/1.1 User-Agent: Fiddler Content-Type: application/json Host: localhost:60060 Content-Length: 16 username=tapuser
  • 我刚刚发布了原始视图。抱歉,缺少格式。

标签: c# rest asp.net-web-api asp.net-mvc-5


【解决方案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

当我的断点被击中时,body/payload 填充了用户名作为 tapuser。

更新

现在虽然上述方法有效,但我并不完全确定它是否解决了你的问题,所以我做了一些谷歌搜索并遇到了这个

Parameter Binding in ASP.NET Web API

其中显示了使用[FromBody] 的以下示例

要强制 Web API 从请求正文中读取简单类型,请添加 [FromBody] 属性到参数:

public HttpResponseMessage Post([FromBody] string name) { ... }

在本例中,Web API 将使用媒体类型格式化程序来读取 请求正文中的名称值。这是一个示例客户端 请求。

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 标头 选择格式化程序。在此示例中,内容类型为 "application/json" 并且请求正文是原始 JSON 字符串(不是 JSON 对象)。

最多允许从消息体中读取一个参数。所以 这不起作用:

// Caution: Will not work!    
public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }

此规则的原因是请求正文可能存储在 只能读取一次的非缓冲流。

当我恢复原始更改并按照示例操作时,它按预期工作。

希望这会有所帮助。

【讨论】:

  • 我尝试了所有这些方法。 Nkosi - 看起来你尝试了与我完全相同的事情,它们对你有用,但对我没有用。所以我不确定发生了什么。
【解决方案2】:

尝试将您的值直接放入请求正文中。看到这个。

【讨论】:

  • 现在回想起来,我意识到您的答案是正确的。我只是没有接受它。非常感谢您的回复。
  • @drunk.. thnx 清除它对于任何基于对象的参数我们不需要使用 [Frombody],但对于简单的我们确实需要。但是,要将参数作为字符串传递,我们确实需要引号(Tim),它不像您所理解的那样在 int 的情况下可能不需要
【解决方案3】:

我发现如果我将“tapuser”放在请求正文中,使用单引号或双引号,它就可以工作。引号似乎是答案。如果我将 tapuser 以外的任何内容放在引号内,则整个内容将作为参数传递。例如,'{username=tapuser}' 将作为 {username=tapuser} 传递。谢谢大家的意见。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-12
    • 1970-01-01
    • 1970-01-01
    • 2019-05-13
    • 1970-01-01
    • 1970-01-01
    • 2011-10-27
    • 2021-05-29
    相关资源
    最近更新 更多