Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Fiddler to send a POST request to WebApi

I'm writing a simple WebApi program, using C#. (I know MVC fairly well, but I'm new to WebApi.) It contains a Vendors controller (VendorsController.cs), which contains a "getvendor" action as shown in the code sample below:

[RoutePrefix("api/vendors")]
public class VendorsController : ApiController
{
    [Route("getvendor"), HttpPost]
    public TAPUser GetVendor([FromBody] string username)
    {
        Int32 userid = -1;

    ...

The routes are configured as follows:

// Web API routes
config.MapHttpAttributeRoutes();

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { action = RouteParameter.Optional, id = RouteParameter.Optional
);

I'm using Fiddler to test the program. First, I ran the above code without [FromBody] and used Fiddler to send a POST request with the username in the url like this: http://localhost:60060/api/vendors/getvendor?username=tapuser

This worked fine. tapuser was passed as the argument to GetVendor and the action returned the expected result.

Next, I added [FromBody] and put username=tapuser in the request body. This time, when I sent the request, tapuser did not get passed to the action. The argument to GetVendor() was null. I've tried variations on the request body such as { "username": "tapuser" }, but it doesn't help. I've tried changing the route in various ways, too, such as changing routeTemplate to "api/{controller}/{action}/{id}". That hasn't helped either. I'm sure I'm missing something very simple, but I just don't see it.

like image 956
Tim Avatar asked Mar 01 '16 01:03

Tim


People also ask

How do you send a POST request on Fiddler?

Sending POST Request To send a new POST request, choose POST for method type, type the URL, enter the body content and click Execute.


2 Answers

Try putting your value directly into the request body. See this. enter image description here

like image 119
drunkcoder Avatar answered Oct 08 '22 01:10

drunkcoder


Now I did some debugging and was able to recreate the issue you were having.

I was eventually able to get the data to the action by doing the following:

First I created a class to act as container for the payload.

public class body {
    public string username { get; set; }
}

and updated the action to match

[Route("getvendor"), HttpPost]
public TAPUser GetVendor([FromBody] body payload) {...}

Then using fiddler I composted the request to the endpoint to test.

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

When my break point was hit the body/payload was populated with the username as tapuser.

UPDATE

Now while the above worked, I wasn't entirely sure that it solved your problem so I did some googling and came across this

Parameter Binding in ASP.NET Web API

Where that showed the following example using [FromBody]

To force Web API to read a simple type from the request body, add the [FromBody] attribute to the parameter:

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

In this example, Web API will use a media-type formatter to read the value of name from the request body. Here is an example client request.

POST http://localhost:5076/api/values HTTP/1.1
User-Agent: Fiddler
Host: localhost:5076
Content-Type: application/json
Content-Length: 7

"Alice"

When a parameter has [FromBody], Web API uses the Content-Type header to select a formatter. In this example, the content type is "application/json" and the request body is a raw JSON string (not a JSON object).

At most one parameter is allowed to read from the message body. So this will not work:

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

The reason for this rule is that the request body might be stored in a non-buffered stream that can only be read once.

When I reverted my original changes and followed the example it worked as intended.

Hope this helps.

like image 38
Nkosi Avatar answered Oct 08 '22 01:10

Nkosi