Search code examples
asp.net-coreasp.net-core-mvcodataasp.net-core-webapi

AspNetCore WebApi ODataController Cannot Deserialize JSON Payload


I am having an trouble getting my V4 ODataController to deserialize a JSON payload. I have created a sample project in github to illustrate my exact issue:

https://github.com/valainisgt/BadODataDeserialization

When the data submitted to the '/odata/models' endpoint using a content-type of application/json, the model is not populated. Using the exact same data keys and values but this time as application/x-www-form-urlencoded, the model is populated.

What am I missing here?

Edit:

Here is what my payload looks like:

{ 'ModelId': 0, 'Name': "John Doe" }

This is an asp.net core application targeting .NET 462.

As such I am using the Microsoft.AspNetCore.* packages.


Solution

  • When the data submitted to the '/odata/models' endpoint using a content-type of application/json, the model is not populated. Using the exact same data keys and values but this time as application/x-www-form-urlencoded, the model is populated.

    1. If you would like to receive a content-type of application/json , you need to decorate your Model with a [FromBody]

      public IActionResult Post([FromBody]Model m)
      

    Test case :

    POST http://localhost:50317/odata/models HTTP/1.1
    Content-Type: application/json
    
    {
        ModelId:11,
        Name:"hello"
    }
    
    1. If you want to receive a content-type of x-www-form-urlencoded , you should add a [Bind()] :

      public IActionResult Post([Bind("ModelId,Name")]Model m)
      

    Test Case :

    POST http://localhost:50317/odata/models HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    
    ModelId=11&Name=hello
    

    However , there's no built-in modelbinder that will bind both data types . If you do want to do that , consider the following approach :

    1. write two action methods and route according to different headers
    2. custom a modelbinder

    For more information , refer docs here