2

I have an API method with this signature:

public async Task<IActionResult> PostCompanies([FromBody] List<Company> companies)

...and the auto generated swagger docs show that the JSON should be a plain array:

 [  
       {
          "fuelSiteId":228972,
          "name": "foo"
       },
       {
          "fuelSiteId":300000010,
          "name": "bar"
       }
 ]

However, if I post this back, it doesn't work and I get the error:

"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Company' because the type requires a JSON object"

The fix is to add the array to a dummy property:

{  
    data: [
       {
          "fuelSiteId":228972,
          "name": "foo"
       },
       {
          "fuelSiteId":300000010,
          "name": "bar"
       }
    ]
}

But everything I'm finding on this site implies this shouldn't be necessary and isn't how you'd normally do it in REST. Additionally, it means what the auto-generated docs say isn't actually what should be posted!

Which is wrong? My API code or the auto-gen Swagger docs or something else?

Ideally I would prefer my API to accept the 'plain' version as this seems more standard and more natural.

NickG
  • 9,315
  • 16
  • 75
  • 115
  • Related: [Is a list/array valid JSON?](https://stackoverflow.com/q/19623339/1220550) – Peter B Nov 09 '18 at 12:33
  • Can you give us an [MCVE](https://stackoverflow.com/help/mcve) please – ADyson Nov 09 '18 at 12:37
  • The correct parameter for your method should be a type that takes an object with a int property and a string property.. FromBody is to handle the post of form data. so if you remove the [FromBody] maybe it works already? The Company type has to have a FuelSiteID (int) and Name (string) property though. – rmjoia Nov 09 '18 at 12:56
  • Yeah the JSON validates fine. – NickG Nov 09 '18 at 14:12
  • @rmjoia My real object has a couple of dozen properties, but I've tried removing FromBody and it doesn't fix the problem. It still needs it assigned to a dummy property to work. – NickG Nov 09 '18 at 14:12
  • I usually use an array like `Company[]` or an `IEnumerable`, but anyway it should work fine. As already asked, please share a [mcve] – Pac0 Nov 09 '18 at 23:16
  • I have found out that I had two duplicate methods and it was hitting a method of the same name which was only expecting a single object. I will delete this question in a couple of days as an "invalid question". – NickG Nov 13 '18 at 16:57

1 Answers1

1

This also works without having to wrap in another type, give it a try. I've tested with Postman

    [HttpPost]
    public JsonResult InsertPatientAppointment([FromBody] List<Company> companies)
    {
        return new JsonResult(companies.Select(c =>
            new
            {
                c.FuelSiteId,
                c.Name,
            }
        ));
    }

    public class Company
    {
        [JsonProperty("fuelSiteId")]
        public int FuelSiteId
        {
            get;
            set;
        }
        [JsonProperty("name")]
        public string Name
        {
            get;
            set;
        }
    }

screenshot on the breackpoint

You can also check other resource on SO how to post json object array to a web api I had to dig a bit myself as I didn't remember anymore how to do this..

As stated at Parameter Binding in ASP.NET Web API: "To force Web API to read a complex type from the URI, add the [FromUri] attribute to the parameter."

Using [FromBody]

rmjoia
  • 962
  • 12
  • 21