How to use Postman when testing .NET Core WebAPI actions with FromBody and FromForm attributes

Postman requires no introductions and plenty of resources about this tool can be found online. However, while testing I recently noticed, that the binding of JSON objects to C# primitive types or POCO classes is not documented in detail.

We are going to see different scenarios of binding while we test against a .NET WebAPI and try to answer the question “why my action is not getting called when everything is set up in Postman?”.

Create a new .NET Core Web project and pick the API template. You will get the standard controller with a number of actions which perform CRUD operations. We only focus on the POST operation and we test the following actions with Postman.

The demo POCO class

    public class TestModel
    {
        public string FirstName { get; set; }

        public string LastName { get; set; }
    }

Examples with POST and FromBody and FromForm

POST with FromBody

    [HttpPost]
    [Route(nameof(PostWithModelWithFromBody))]
    public ActionResult<string> PostWithModelWithFromBody([FromBody] TestModel model)
    {
        return model.FirstName;
    }

Post with model with the FromBody attribute

POST without FromBody

    [HttpPost]
    [Route(nameof(PostWithModelWithoutFromBody))]
    public ActionResult<string> PostWithModelWithoutFromBody(TestModel model)
    {
        return model.FirstName;
    }

Post with model without the FromBody attribute

POST with parameter and with FromBody

    [HttpPost("{id}/PostWithGetParameterAndModelWithFromBody")]
    [Route(nameof(PostWithGetParameterAndModelWithFromBody))]
    public ActionResult<string> PostWithGetParameterAndModelWithFromBody(int id, [FromBody] TestModel model)
    {
        return model.FirstName;
    }

Post with one GET parameter and a model with the FromBody attribute

POST with parameter, primitive value and with FromBody

    [HttpPost("{id}/PostWithGetParameterAndPrimitiveWithFromBody")]
    [Route(nameof(PostWithGetParameterAndPrimitiveWithFromBody))]
    public ActionResult<string> PostWithGetParameterAndPrimitiveWithFromBody(int id, [FromBody] string firstName)
    {
        return firstName;
    }

Post with one GET parameter and a primitive type with the FromBody attribute

POST with primitive value and with FromForm

    [HttpPost("{id}/PostWithPrimitiveWithFromForm")]
    [Route(nameof(PostWithPrimitiveWithFromForm))]
    public ActionResult<string> PostWithPrimitiveWithFromForm(int id, [FromForm] string firstName)
    {
        return firstName;
    }

Post with a primitive type with the FromForm attribute

To conclude, here are the take-aways when using FromBody and FromForm:

Drop me a line if you have any questions or remarks.

comments powered by Disqus