Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Controller action not reading Guid POST from JSON

I have a Controller action declared as:

[Route("api/person")]
[HttpPost]
public async Task<IActionResult> Person([FromBody] Guid id) { ... }

I am posting to it with:

POST /api/person HTTP/1.1
Host: localhost:5000
Content-Type: application/json
Cache-Control: no-cache
Postman-Token: 747a5d76-398c-e1c7-b948-b276bb24976c

{
    "id": "b85f75d8-e6f1-405d-90f4-530af8e060d5"
}

My action is being hit, but the Guid that it receives is always a Guid.Empty value (ie: it's not getting the value I'm passing it).

Note, this works fine if I use url parameters instead of [FromBody], but I'd like to use the body of the http post instead.

like image 823
mariocatch Avatar asked May 24 '16 03:05

mariocatch


1 Answers

As described in Web API documentation:

By default, Web API uses the following rules to bind parameters:

  • If the parameter is a “simple” type, Web API tries to get the value from the URI. Simple types include the .NET primitive types (int, bool, double, and so forth), plus TimeSpan, DateTime, Guid, decimal, and string, plus any type with a type converter that can convert from a string. (More about type converters later.)
  • For complex types, Web API tries to read the value from the message body, using a media-type formatter.

Further in the same article in section Using [FromBody] you can see the sample that you can add attribute [FromBody] on your parameter in order to bind the value from the request body, just like you did. But here is the catch - sample shows, that in this case request body should contain raw value, not JSON object.

So in your case you have 2 options:

First option is to change your request to provide raw value instead of a JSON object

POST /api/person HTTP/1.1
Host: localhost:5000
Content-Type: application/json
Cache-Control: no-cache
Postman-Token: 747a5d76-398c-e1c7-b948-b276bb24976c

"b85f75d8-e6f1-405d-90f4-530af8e060d5"

Second option is to provide complex object with single property and use it as parameter:

public class Request
{
    public Guid Id { get; set; }
}

[Route("api/person")]
[HttpPost]
public async Task<IActionResult> Person([FromBody] Request request) { ... }
like image 93
dotnetom Avatar answered Nov 16 '22 03:11

dotnetom