I'm looking to send the following fields to a MVC action
public class AddProductViewModel
{
    public string ProductId { get; set; }
    public string ProductName { get; set; }
    public int Quantity { get; set; }
    public double Price { get; set; }
    public bool Enabled { get; set; }
    public List<CategorySelectModel> Categories { get; set; } = new List<CategorySelectModel>(); 
    public List<IFormFile> Photos { get; set; } = new List<IFormFile>();
}
CategorySelectModel:
    
    public string CategoryId { get; set; }
    public string CategoryName { get; set; }
and I haved used what i believe represents the actual json data...but I dont get why it isnt posting the data to the action here is the js code where I have serialized the data and send to the controller
function SubmitProducts(element)
{
    element.preventDefault();
    let ulContainer = document.getElementById("dropDownAndSel").getElementsByTagName('ul')[0];
    var Categories = [];
    let x = document.getElementById("dropDownCategories");
    for (let i = 0; i < x.children.length; i++) {
        if (x.options[i].selected) {
           let CategoryName = x.options[i].innerHTML;
            let CategoryId = x.children[i].value;
            let dropdownItems = { CategoryId, CategoryName };
            if (!Categories.includes(dropdownItems)) {
                Categories.push(dropdownItems);
            }
        }
    }
    let pId = document.getElementById('pId').value;
    let ProductId = pId;
    let ProductName = document.getElementById('ProductName').value;
    if (!ProductName || ProductName.length ==0) {
        alert('ProdutName cannot be null or empty');
        return;
    }
    let priceStr = document.getElementById('productPriceId').value;
    if (!priceStr || priceStr.length == 0) {
        alert('Price cant be empty')
        return;
    }
    let Price = parseFloat(priceStr);
    
    let QuantityStr = document.getElementById('qtyNum').value;
    if (!QuantityStr || QuantityStr.length==0) {
        alert('Quantity cant be empty');
        return;
    }
    let Quantity = parseInt(QuantityStr);
 
    var formData = new FormData();
    let filesContainer = document.getElementById('photoProduct_0');
    for (let i = 0; i < filesContainer.files.length; i++) {
        formData.append('model.Photos', filesContainer.files[i], filesContainer.files[i].name);
    }
    formData.set('model.ProductId', ProductId);
    formData.set('model.ProductName', ProductName);
    formData.set('model.Price', Price);
    formData.set('model.Quantity', Quantity);
    formData.set('model.Categories', JSON.stringify(Categories));
    $.ajax({
        url: '/' + 'Product' + '/' + 'AddProduct',
        type: 'POST',
        contentType: false,
        processData: false,
        data: formData,
        success: console.log('success'),
    });
}
Here is the action signature:
[HttpPost]
public async Task<IActionResult> AddProduct([FromBody] AddProductViewModel model)
 
    