'Cannot deserialize the current JSON object .Net Core 5

I have a .Net Core 5 solution that is largely he same as another previous, working solution. In both the controllers are .Net Core 5. In the previous, working one, the services, models and view models are in a 4.7 project. Most of the new solution is working, except for one controller that takes a nested (master/detail) JSON sent in the body of the request. The service is set up to deserialize the JSON into a dataset. The JSON shows as valid in the jsonlint.com validator. However, I keep getting this error in Postman: "Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.IList`1[Sage100_API.ViewModels.APInvoiceReq]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.\r\nTo fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.\r\nPath 'APInvoiceRequest', line 2, position 21."

[JsonObjectAttribute] is already in place in the viewmodels involved. The error occurs when stepping off the final curly bracket in this code in the controller:

public APInvoiceResponseController(IAPInvoiceService apInvoiceService, IOptions<AppSettingsModel> app)
    {
        APInvoiceService = apInvoiceService;
        AppSettings = app;
    }

What is different between core 5 and 4.7 in deserializing in NewtonSoft JSON?

edit: adding JSON and code JSON:


     {
      "APInvoices": {
        "APInvoice": [
          {        
            "APDivisionNo": "00",
            "APVendorNo": "0000006",        
            "PayeeTermsCd": "00",
            "HoldPayment": "N",
            "SeparateCheck": "N",
            "InvoiceNo": "12345",
            "InvoiceDate": "2022-04-06",        
            "BatchNmbr": "490",        
            "TotalAmount": 150,
            "APInvoiceDetails": {
              "APInvoiceDetail": [
                {
                  "InvoiceNo": "12345",
                  "Line": "1",
                  "Amount": "25.7500",
                  "GLAcctID": "5000-00-10",              
                  "Comment": "line 1 comment",
                  "BatchNmbr": "490"
                },
                {
                  "InvoiceNo": "12345",
                  "Line": "2",
                  "Amount": "75.2500",
                  "GLAcctID": "5000-00-10",              
                  "Comment": "line 2 comment",
                  "BatchNmbr": "490"
                },
                {
                  "InvoiceNo": "12345",
                  "Line": "3",
                  "Amount": "49.00",
                  "GLAcctID": "5000-00-10",              
                  "Comment": "line 3 comment",
                  "BatchNmbr": "490"
                }
              ]
            },
            {        
            "APDivisionNo": "00",
            "APVendorNo": "0000006",        
            "PayeeTermsCd": "00",
            "HoldPayment": "N",
            "SeparateCheck": "N",
            "InvoiceNo": "12346",
            "InvoiceDate": "2022-04-06",        
            "BatchNmbr": "490",        
            "TotalAmount": 150,
            "APInvoiceDetails": {
              "APInvoiceDetail": [
                {
                  "InvoiceNo": "12345",
                  "Line": "1",
                  "Amount": "25.7500",
                  "GLAcctID": "5000-00-10",              
                  "Comment": "line 1 comment",
                  "BatchNmbr": "490"
                },
                {
                  "InvoiceNo": "12345",
                  "Line": "2",
                  "Amount": "75.2500",
                  "GLAcctID": "5000-00-10",              
                  "Comment": "line 2 comment",
                  "BatchNmbr": "490"
                },
                {
                  "InvoiceNo": "12345",
                  "Line": "3",
                  "Amount": "49.00",
                  "GLAcctID": "5000-00-10",              
                  "Comment": "line 3 comment",
                  "BatchNmbr": "490"
                }
              ]
            }
          }
        ]
      }
    }

Controller:


        {
        [ApiController]
        public class APInvoiceResponseController : ControllerBase
        {
            //private readonly S100Entities Context;
            private readonly IAPInvoiceService APInvoiceService;
            private readonly IOptions<AppSettingsModel> AppSettings;
            public APInvoiceResponseController(IAPInvoiceService apInvoiceService, IOptions<AppSettingsModel> app)
            {
                APInvoiceService = apInvoiceService;
                AppSettings = app;
            }
    
            [HttpPost]
            [Route("apinvoice")]
            public async Task<IActionResult> Basic([FromBody] IList<APInvoiceReq> apInvoice)
            {           
                try
                {
                    
                        var APInvoices = await APInvoiceService.PostAPInvoices(apInvoice);
                        try
                        {
                            if (apInvoice == null)
                            {
                                return BadRequest("Missing transaction data.");
                            }
    
                            if (APInvoices == null)
                            {
                                return NotFound();
                            }
    
                            return Ok(APInvoices);
                        }
    
                        catch (System.Exception e)
                        {
                            Serilog.Log.Error("Error in APInvoices", e);
                            APInvoices.SuccessErrorWarningResult.AddError(666, e.ToString());
                            return Ok(APInvoices);
                        }                
                }
                catch (System.Exception e)
                {
                    Serilog.Log.Error("Error in APInvoices", e);                
                    return BadRequest();
                }
    
            }
    
        }
    }

APInvoiceReq class:

{
    [JsonObjectAttribute]
    [JsonArray]
    [Serializable]
    public class APInvoiceReq : S100Object<APInvoiceReq>
    {
        public string APDivisionNo { get; set; }
        public string APVendorNo { get; set; }        
        public string PayeeTermsCd { get; set; }
        public string HoldPayment { get; set; }
        public string SeparateCheck { get; set; }
        public string InvoiceNo { get; set; }
        public DateTime InvoiceDate { get; set; }
        public string InvoiceComment { get; set; }
        public int BatchNmbr { get; set; }  //UDF_BATCH_NO
        public decimal TotalAmount { get; set; }
        public IEnumerable<APInvoiceDetail> APInvoiceDetails { get; set; }
    }
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source