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.
Sending POST Request To send a new POST request, choose POST for method type, type the URL, enter the body content and click Execute.
Try putting your value directly into the request body. See this.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With