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 ValuesController with a number of actions which perform CRUD operations. We only focus on the POST operation and we want to test the following actions with Postman.

The demo POCO class

1
2
3
4
5
6
    public class TestModel
    {
        public string FirstName { get; set; }

        public string LastName { get; set; }
    }

Examples with POST and FromBody and FromForm

1
2
3
4
5
6
    [HttpPost]
    [Route(nameof(PostWithModelWithFromBody))]
    public ActionResult<string> PostWithModelWithFromBody([FromBody] TestModel model)
    {
        return model.FirstName;
    }

Post with model with the FromBody attribute


1
2
3
4
5
6
    [HttpPost]
    [Route(nameof(PostWithModelWithoutFromBody))]
    public ActionResult<string> PostWithModelWithoutFromBody(TestModel model)
    {
        return model.FirstName;
    }

Post with model without the FromBody attribute


1
2
3
4
5
6
    [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


1
2
3
4
5
6
    [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


1
2
3
4
5
6
    [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 offs when using FromBody and FromForm:

  • Use a valid JSON object to bind to FromBody

  • The use of the FromBody attribute is optional. I personally suggest to use this attribute, since it clarifies how the binding is going to happen. If you have a primitive type with no FromForm attribute, then no binding will happen

  • Use the form-data Key-Value pairs in Postman when binding to the FromForm attribute

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

comments powered by Disqus