Search code examples
jqueryajaxasp.net-mvcmultipartform-dataform-data

How can we map a c# complex list object from FormData in MVC through Jquery


I have a list object in my controller. I need to map this List object with the data which is getting passed to controller in an Ajax call from FormData. The reason why i am using FormData is, i need to get some files from the view in this same ajax call.

Please find my code below

 public class AdModel
{
    public PartsAd PartsAdModel { get; set; }
    public List<HttpPostedFileBase> AdImages { get; set; }
}
public class PartsAd
{
    public List<Vehicle> VehicleList { get; set; }
}
public class Vehicle
{
    public string VehicleBrand { get; set; }
}

Below is my action method in controller

 public ActionResult AjaxPostAd(AdModel adModel)
    {
    }

Below is my Jquery Code

var applicableVehicleBrands = $('#multiSelectApplicableVehicleBrand option:selected');
    var selectedBrand = 0;
    $(applicableVehicleBrands).each(function () {
        data.append("adModel[PartsAdModel.VehicleList[" + selectedBrand + "].VehicleBrand]", $(this).val())
        selectedBrand = selectedBrand + 1;
    });
 $.ajax({
    cache: false,
    type: "post",
    async: true,
    url: "" + ajaxPostURL + "",
    data: data,
    contentType: false,
    processData: false,
    success: function (data) {});

But in my controller, when i look for adModel.PartsAdModel.VehicleList, it is null

Can somebody please help me?


Solution

  • For model binding to work, your form data should have properties with this name

    PartsAdModel.VehicleList[{n}].VehicleBrand
    

    Where {n} is the zero based index of the array of vehicle items you want to send.

    You do not need the adModel prefix in the formd data item name as model binder will not care about the parameter name you use in your HttpPost action method.

    The below code should work. I just hard coded 2 items for the VehicleList property. You may update it so that it dynamically add item (in a loop) based on your DOM inputs.

    var data = new FormData();
    
    data.append("PartsAdModel.VehicleList[0].VehicleBrand", "Honda");
    data.append("PartsAdModel.VehicleList[1].VehicleBrand", "Toyota");
    
    // Add the uploaded file
    // Assuming you have a file input with name="AdImages"
    $('input[name="AdImages"]').each(function(a, b) {
        var fileInput = $('input[name="AdImages"]')[a];
        if (fileInput.files.length > 0) {
            var file = fileInput.files[0];
            data.append("AdImages", file);
        }
    });
    
    
    $.ajax({
        type: "post",
        url: '@Url.Action("AjaxPostAd")',
        data: data,
        contentType: false,
        processData: false
    }).done(function(r) {
        console.log('ajax call done');
    });