简体   繁体   中英

How to map Mvc View model and ajax post data which have list property?

I have a MVC controller action with inputModel parameter which have list type property and , I ,m using $('form').serialize() to serialize the form content and append some of my custom data to serialized string, but inside the action method input model object the list property is empty, Can any one help me , below is the code samples

My controller

[HttpPost]
public ActionResult Edit(ALDS.Web.Areas.Direct2M3.Models.ItemInputModel collection)
{   }

ItemInputModel class

 public class ItemInputModel
    {
        //......Some property here..
        public List<FabricCompositionInputModel> FabricCompositions { get; set; }
    }

FabricCompositionInputModel class

 public class FabricCompositionInputModel
    {
        public int ItemID { get; set; }
        public string CompositionCode { get; set; }
        public decimal Value { get; set; }

    }

Ajax call

function save() {

    var compositionData = generateCompositionForSave(); //Returns array
    var data = $('form').serialize();
    var d2 = JSON.stringify(compositionData);

    var data2 = data + '&FabricCompositions=' + d2;

    $.ajax({
        type: 'POST',
        dataType: 'json' ,
        cache: false,
        url: '/ItemMaster/Edit',
        data: data2,
        success: function (data, textStatus, jqXHR) {
            sucess(data);
        },
        error: function (jqXHR, textStatus, errorThrown) {
            failed(jqXHR);
        }

    });

}

Array generating function

function generateCompositionForSave() {
    var arr = [];
    var delClassList = $('#compositionContainer').find('.btnRemoveCompositions');
    for (var c = 0; c < delClassList.length; c++) {
        var row = $(delClassList[c]).closest('.row');
        var code = row.find('.compositionCode').val();
        var value = parseInt(row.find('.compositionValue').val());
        arr.push({ItemID:0, CompositionCode:code, Value:value});
    }

    return arr;
}

Your not building the data correctly, and it needs to be

var compositionData = generateCompositionForSave();
var data = $('form').serializeObject(); // see function below
data['FabricCompositions'] = compositionData; // add the array to the serialized data
var data2 = JSON.stringify({ collection: data }), // stringify it

$.ajax({
    type: 'POST',
    contentType: "application/json; charset=utf-8", // add contentType
    dataType: 'json' ,
    cache: false,
    url: '@Url.Action("Edit", "ItemMaster")', // don't hard code your url's
    data: data2,
    success: function (data, textStatus, jqXHR) {
        ....

And add the following function (warning: this will not work correctly for a <select multiple> element)

$.fn.serializeObject = function () {
    var o = {};
    var a = this.serializeArray();
    $.each(a, function () {
        if (o[this.name] === undefined) {
            o[this.name] = this.value || '';
        }
    });
    return o;
};

Note that if you generate your form controls correctly using a for loop or custom EditorTemplate for typeof FabricCompositionInputModel (refer Post an HTML Table to ADO.NET DataTable ), for example

for(int i = 0; i < Model.FabricCompositions.Count; i++)
{
    @Html.TextBoxFor(m => m.FabricCompositions[i].CompositionCode)
    @Html.TextBoxFor(m => m.FabricCompositions[i].Value)
}

then all that is required is

var data = $('form').serialize();
$.ajax({
    type: 'POST',
    dataType: 'json' ,
    cache: false,
    url: '@Url.Action("Edit", "ItemMaster")',
    data: data,
    success: function (data, textStatus, jqXHR) {

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM