C# 使用Fiddler向WebApi发送POST请求

C# 使用Fiddler向WebApi发送POST请求,c#,rest,asp.net-web-api,asp.net-mvc-5,C#,Rest,Asp.net Web Api,Asp.net Mvc 5,我正在用C编写一个简单的WebApi程序。我对MVC相当了解,但我对WebApi还不熟悉。它包含一个Vendors controller VendorsController.cs,其中包含一个getvendor操作,如下面的代码示例所示: [RoutePrefix("api/vendors")] public class VendorsController : ApiController { [Route("getvendor"), HttpPost] public TAPUse

我正在用C编写一个简单的WebApi程序。我对MVC相当了解,但我对WebApi还不熟悉。它包含一个Vendors controller 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请求,如下所示:

这很有效。tapuser作为参数传递给GetVendor,操作返回预期结果


接下来,我添加了[FromBody],并将username=tapuser放在请求正文中。这一次,当我发送请求时,tapuser没有被传递到操作。GetVendor的参数为null。我在请求主体上尝试了{username:tapuser}等变体,但没有任何帮助。我也尝试过以各种方式更改路由,例如将routeTemplate更改为api/{controller}/{action}/{id}。这也没用。我确信我遗漏了一些非常简单的东西,但我就是看不到。

现在我进行了一些调试,并能够重新创建您遇到的问题

通过执行以下操作,我最终能够获取操作的数据:

首先,我创建了一个类作为有效负载的容器

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填充

更新

现在,虽然上述方法有效,但我不能完全确定它是否解决了您的问题,所以我在谷歌上搜索了一下,发现了这个问题

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

要强制Web API从请求主体读取简单类型,请添加 参数的[FromBody]属性:

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

当参数具有[FromBody]时,Web API使用内容类型标头 选择格式化程序。在本例中,内容类型为 application/json,请求主体是原始json字符串,而不是 JSON对象

最多允许从消息体读取一个参数。所以 这是行不通的:

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

当我恢复原来的更改并遵循示例时,它按预期工作


希望这有帮助。

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

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

您是否确保在请求头中将内容类型指定为application/json?如果仍未解决,您是否可以共享fiddler屏幕截图/代码。旁注:fiddler请求的原始视图(文本形式)比imagePOST HTTP/1.1用户代理更好:fiddler内容类型:应用程序/json主机:本地主机:60060内容长度:16用户名=tapuserI刚刚发布了原始视图。很抱歉缺少格式。我尝试了所有这些方法。恩科西-看起来你尝试了与我完全相同的事情,它们对你有效,但对我无效。所以我不确定发生了什么。现在我回头看看,我意识到你的答案是正确的。我只是没有意识到。所以谢谢你的回答。@喝醉了。。thnx用于澄清,对于任何基于对象的参数,我们不需要使用[Frombody],但对于简单的参数,我们确实需要。然而,要将参数作为字符串传递,我们确实需要引号,而不是像您理解的那个样,在int的情况下可能不需要引号
public HttpResponseMessage Post([FromBody] string name) { ... }
POST http://localhost:5076/api/values HTTP/1.1
User-Agent: Fiddler
Host: localhost:5076
Content-Type: application/json
Content-Length: 7

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