0
function myItemsViewModel(ItemID, GroupID, ItemName, Quantity) {
this.ItemID = ItemID;
this.GroupID = GroupID;
this.ItemName = ItemName;
this.Quantity = Quantity;

}

And i have below code for posting to the controller

 var CreateRecord = function () {
    var Name = $.trim($("#divCreate").find("#txtName").val());
    var Department  = $.trim($("#divCreate").find("#txtDepartment").val());

    var ItemsList = [];
    $('#myDynamicTable').find('tr').each(function () {
        var row = $(this);
        var itemName = $.trim(row.find(".itemName input").val());
        var itemQty = $.trim(row.find(".itemQty input").val());

        var myItems = new myItemsViewModel("", "", itemName, itemQty);
        ItemsList.push(myItems);
    });

    var obj = new myRecordEntryViewModel("", Name, Department, ItemsList);
    var viewmodel = JSON.stringify(obj);    
                $.ajax({
                    type: 'POST',
                    cache: false,
                    dataType: 'html',
                    data: viewmodel,
                    headers: GetRequestVerificationToken(),
                    contentType: 'application/json; charset=utf-8',
                    url: '/' + virtualDirectory + '/RecordEntry/Save',
                    success: function (data) {
                        $("#divMaster").html(data);
                        return false;
                    },
                    error: function (msg) {
                        alert("Error Submitting Record Request!");
                    }
                });
            }

At the line var viewmodel = JSON.stringify(obj);, viewmodel has all the values that i want in my ItemsList array variable.

Problem is my ItemsList array is coming as null in the controller. Name and Department are coming through with the correct passed values.

Below is my controller code.

Class

 public class myRecordEntryViewModel 
    {
        public  long ID { get; set; }
        public  string Name { get; set; }
        public string Department { get; set; }
        public string[] ItemsList { get; set; }
    }

Save action

    [ActionName("Save")]
    [NoCache]
    public ActionResult Save(myRecordEntryViewModel viewModel)
    {
            //here viewModel.ItemsList is null, what could i be missing
            if (this.SaveEntry(viewModel.Name,viewModel.Department,viewModel.ItemsList))
            {

            }
        return this.View();
    }

I'm wondering why viewModel.ItemsList is coming as null in controller yet it has values during the post from jQuery.

StackTrace
  • 9,190
  • 36
  • 114
  • 202
  • `ItemsList` in your model is `string[]` but you script appears to be generating an array of javascript objects containing multiple properties (what is `myItemsViewModel`?) –  Mar 17 '15 at 08:56
  • Can you show the JSON string of the view model? – Huy Hoang Pham Mar 17 '15 at 08:56
  • @StephenMuecke, i have edited my post to add "myItemsViewModel" – StackTrace Mar 17 '15 at 09:01
  • 1
    So is `public string[] ItemsList` correct? - you cant post an array of complex objects to `string[]`. –  Mar 17 '15 at 09:04
  • 1
    @SQL.NETWarrior. If you change `ItemsList` to `var ItemsList = [ 'abc', 'def' ];` and add `traditional: true,` to the ajax options, you will see that you model is correctly bound. Otherwise you need to change `ItemsList` to `IEnumerable` where `ItemsModel` contains the 4 properties in `myItemsViewModel` –  Mar 17 '15 at 09:21

3 Answers3

1

There are several problems in your codes...

1) ItemList in your class and your javascript code are not same - The frist one is an array of strings, and the second is an array of objects

2) In your action method, you should change parameter type like the following:

public ActionResult Save(string viewModel)

3) In the body of your action method, you should deserialize the json string (viewModel) and make the model object from it. The following is an example...

https://stackoverflow.com/a/17741421/1814343

Community
  • 1
  • 1
Amin Saqi
  • 18,549
  • 7
  • 50
  • 70
  • dataType: specifies the data that is returned from the method, and the method returns a view (i.e. html). OP has a model so why on earth would you bind to a string. The `DefaultModelBinder` takes care of all this for you. –  Mar 17 '15 at 09:14
  • @StephenMuecke Oh yeah you're right. It was my mistake about dataType and contentType. Thank you! – Amin Saqi Mar 17 '15 at 09:51
1

You should create a class for the Item in Item List (In C#)

public class Item {
    public string ItemName { get; set; }
    public int Quantity { get; set; }
}

And then change the viewmodel class

 public class myRecordEntryViewModel 
{
    public  long ID { get; set; }
    public  string Name { get; set; }
    public string Department { get; set; }
    //public string[] ItemsList { get; set; }
    public List<Item> ItemsList {get ; set;}
}

The controller can not map the Item List from your request into model because one is a list of string and other is a list of object.

Huy Hoang Pham
  • 4,107
  • 1
  • 16
  • 28
0

Try the below code and see if your model gets the values. Let me know if you face any problems, because I've already implemented this in one of my projects

var CreateRecord = function () {
    var Name = $.trim($("#divCreate").find("#txtName").val());
    var Department  = $.trim($("#divCreate").find("#txtDepartment").val());
    var model="";
    var ItemsList = [];
    $('#myDynamicTable').find('tr').each(function () {
        var row = $(this);
        var itemName = $.trim(row.find(".itemName input").val());
        var itemQty = $.trim(row.find(".itemQty input").val());

        var myItems = new myItemsViewModel("", "", itemName, itemQty);
        ItemsList.push(myItems);
    });
    model = ['Name' : Name , 'Department' : Department , 'ItemsList' :ItemsList];
       $.ajax({
                    type: 'POST',
                    cache: false,
                    dataType: 'html',
                    data: JSON.stringify(model),
                    headers: GetRequestVerificationToken(),
                    contentType: 'application/json; charset=utf-8',
                    url: '/' + virtualDirectory + '/RecordEntry/Save',
                    success: function (data) {
                        $("#divMaster").html(data);
                        HideLoader();
                        return false;
                    },
                    error: function (msg) {
                        alert("Error Submitting Record Request!");
                        HideLoader();
                    }
                });
            }
Guruprasad J Rao
  • 29,410
  • 14
  • 101
  • 200