1

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)
Jackdaw
  • 7,626
  • 5
  • 15
  • 33
PontiacGTX
  • 185
  • 2
  • 15

1 Answers1

1

Code above post FormData data. Therefore, the AddProductViewModel parameter should be bound using form-data in the request body:

[HttpPost]
public async Task<IActionResult> AddProduct([FromForm] AddProductViewModel model)

Reference to the following post: ASP.NET Core form POST results in a HTTP 415 Unsupported Media Type response

Jackdaw
  • 7,626
  • 5
  • 15
  • 33
  • I have found that it doesnt send the data for cateogry even it is serialized a this i dont get it why it isnt working – PontiacGTX Feb 07 '22 at 14:02
  • 0: "model.Categories" 1:"[{"CategoryId":"93086896-8f67-4861-b9c8-c18fe16bf9a4","CategoryName":"Sweater"},{"CategoryId":"99086896-8f67-4861-b9c8-c18fe16bf9a4","CategoryName":"Jeans"}]" – PontiacGTX Feb 07 '22 at 14:02
  • @PontiacGTX: I.e. when you pass this data to the `.ajax` call, in the `AddProduct()` method the `AddProductViewModel` contains `null` in the `Categories`? – Jackdaw Feb 07 '22 at 20:18
  • the solution was doing as if i assigned the value in C # each time because apparently you cant load an entire string and pretend it serialized in the form automatically formData.append('model.Categories[' + index + '].CategoryName', CategoryName); formData.append('model.Categories[' + index + '].CategoryId', CategoryId); – PontiacGTX Feb 07 '22 at 20:33
  • 1
    @PontiacGTX: How to properly pass a list of objects to the controller method you can see in the following post: [Passing A List Of Objects Into An MVC Controller Method Using jQuery Ajax](https://stackoverflow.com/q/13242414/6630084). – Jackdaw Feb 07 '22 at 20:44
  • it is a bit different with FormData but I will keep it in mind thank you – PontiacGTX Feb 07 '22 at 20:46