Search code examples
c#.netpostman

Why is "[FromBody]string json" null when coming from Postman?


When I call this API method from my unit test, the json parameter has a value. But when I do it from Postman, it's always null.

/// <summary>
/// Save the access integration settings for a given integration.
/// </summary>
/// <param name="json"></param>
/// <param name="integrationID"></param>
/// <returns></returns>
[Route("api/AccessIntegrationSettings/{integrationID}")]
[SwaggerOperation(Tags = new[] { "Access Integration: Integration Settings" })]
public IHttpActionResult Post([FromBody]string json, string integrationID)
{
    ....
}

Here's what I'm doing in Postman (pictures are easier...)

enter image description here

For headers, there are two security headers (which are not the issue) and this one too:

Content-Type    application/json

I'm not sure if I have my method improperly configured, or if my call from Postman is wrong. But again, when I hit this method from a unit test, the json parameter has a value, so I'm inclined to think that I'm doing something wrong in Postman, but I don't know what.

UPDATE:

I've also noticed that if I validate the ModelState, it's always true when coming from the unit test, and always false when coming from Postman.

public override void OnActionExecuting(HttpActionContext actionContext)
{
     if (actionContext.ModelState.IsValid == false)
     {
         ....
     }
}

If I drill into the ModelState from each call, there is an extra key-value pair when coming from Postman that isn't there when coming from my unit test:

key:   json
value: null

Solution

  • You should use parameter binding, Asp.Net would deserialize the json instead of you.

    So, try to use complex object in action parameters.

    public class SampleJson
    {
        public bool IntegrationEnabled { get; set; }
    
        public bool SyncUsers { get; set; }
    
        //etc...
    }
    

    Also, add HttpPost attribute for your action.

    [HttpPost]
    public IHttpActionResult Post(SampleJson jsonObject, [FromUri]string integrationID)
    

    EDIT

    If you want to handle multiple types, you can merge the objects like this;

    public class RootJson
    {
        public SampleJson SampleJson { get; set; }
    
        public AnotherSampleJson AnotherSampleJson { get; set; }
    }
    

    And you can check simple null control for that properties.

    Note : Keep in mind that, merging the complex objects changes the json. It should be surrounded with root brackets.