TL;DR;
The purpose of this article is to show is how to transmit data to edit( create, update, delete) from a MVVM array to an ASP.NET MVC action in order for the action to bind to an IEnumerable/Array/List of objects. We will make also a javascript function that can be re-use across multiple MVVM frameworks to transmit data for multiple objects at once.
As always, you can find source code at https://github.com/ignatandrei/JavaScriptAndMVVMandMVC/ and you can view online at http://mvvmjavascriptmvc.apphb.com/
If you know already that, the last item on this rather long post is a homework. Download code and do it 
Prerequisites:
- If you want to know about ajax, please see the same example of how to save employee one by one http://msprogrammer.serviciipeweb.ro/2011/12/05/jquery-ajax-request-and-mvcdetailed/.
- The reference of sending an array of objects to MVC is http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/ . Please read it first since we will compose the Http request in ASP.NET MVC manner.
- If you do not know about MVVM and data binding in javascript, please follow most comprehensive tutorial that I know, http://learn.knockoutjs.com/
Objects
We start with the Employee ( Id, Name and IdDepartment) and Department(Id, Name). We will make an interface to display and edit multiple employees. The user can choose to change the Name and pick a Department from a list of Departments (presented as a select / dropdown / combox) .Also, he can create new Employee or delete an existing Employee. Then the user can submit all changes at once. We will use for this MVVM from Knockout, but you can use any other MVVM framework.
We will have 2 modes: edit and display. For edit, we have as actions add, delete ,modify and send all modifications(along with validation) . I would list what it is mandatory for every mode and action.
For fast learners:
Display
Edit Mode –Modify existing data
Edit Mode –add new employee
Edit Mode –delete existing employee
Edit Mode –send modifications and client validation
Summary
Homework

As you see we need to display the Employee list with name and the Department name.
If I do not want to create a NameDepartment property on Employee, but just use DepartmentId then the Model of the View should return the list of names of Departments.
1 2 3 4 5 6 7 | public class ListEmployeesViewModel
{
public employeeList AllEmployees { get ; set ; }
public departmentList DepartmentList{ get ; private set ; }
|
This will be serialized as javascript array in the Home view:
1 2 3 4 5 6 7 8 9 | @{
var jss = new JavaScriptSerializer();
var arrDepartments = jss.Serialize(Model.DepartmentList);
var arrEmployees = jss.Serialize(Model.AllEmployees);
}
|
1 2 3 4 5 6 7 8 | var arrDeps = @Html.Raw(arrDepartments) ;
var arrEmps = @Html.Raw(arrEmployees) ;
|
So we have in arrDeps the departments and in arrEmps the existing employees.
To display the list of employees we create a MVVM javascript model( we have here knockout style, but is similar with other javascript MVVM framework)
First we create an employee in javascript ( explanations will follow) :
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | var emp = function (empId,name,deptId,active){
var self = this ;
self.nr = i++;
self.IdEmployee = ko.observable(empId);
self.NameEmployee = ko.observable(name);
self.Active = ko.observable(active);
self.iddepartament = ko.observable(deptId);
self.editMode = ko.observable( false );
self.displayMode= ko.observable( true );
self.deptName= function (){
var id=self.iddepartament();
var name = "" ;
$.each(arrDeps, function (index,value){
if (value.IdDepartment == id){
name=value.NameDepartment;
return false ;
}
});
return name;
}
}
|
Explanation 1: the nr is the number of the employee . The user does not like ID, but wants to know how much employees are displayed.
Explanation 2: I have add an editMode and displayMode to the employee – to know the mode in which the employee is. I can have one property instead of 2(because of complementarity) , but was easier for me.
Explanation 3: In order to display DepartmentName it is enough to create a function on the employee to return the department name , iterating through the arrDeps – the code is
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 | self.deptName= function (){
var id=self.iddepartament();
var name = "" ;
$.each(arrDeps, function (index,value){
if (value.IdDepartment == id){
name=value.NameDepartment;
return false ;
}
});
return name;
}
|
Now we create the javascript model that holds all employees on the view:
1 2 3 4 5 | var jsModel = function () {
var self = this ;
self.employees = ko.observableArray([]);
|
And we make a function to add the existing employees to the array of employees:
1 2 3 4 5 | self.addEmp = function (empId,name,deptId,active) {
self.employees.push( new emp(empId,name,deptId,active))
};
|
And we add to the javascript MVVM model the existing employees
1 2 3 4 5 6 7 | var model= new jsModel();
$.each(arrEmps, function (index,value){
model.addEmp(value.IdEmployee ,value.NameEmployee, value.iddepartament,value.Active);
});
|
And display it on the template by just binding :
that will repeat in
<tbody data-bind=’foreach: employees’>
<tr>
<td>
<span data-bind=’text: nr’ > </span>
</td>
<td>
<span data-bind=’text: NameEmployee,visible:displayMode’> </span>
<!—code removed for clarity–>
</td>
<td>
<span data-bind=’text: deptName(),visible:displayMode’> </span>
<!—code removed for clarity–>
</td>
<td>
<span data-bind=’text: Active,visible:displayMode’> </span>
<!—code removed for clarity–>
</td>
<td><!—code removed for clarity–>
</td>
</tr>
So this was the display mode. Pretty simple, huh ?
Edit Mode –Modify existing data
The Edit button calls the javascript model edit(true):
01 02 03 04 05 06 07 08 09 10 11 | self.edit = function (val){
var arr =self.employees();
$.each(arr , function (index,value){
value.editMode(val);
value.displayMode(!val);
});
|
So I put editMode to true and displayMode to false
Now, back to the template:
<td>
<span data-bind=’text: NameEmployee,visible:displayMode’> </span>
<input data-bind=’value: NameEmployee,visible:editMode’ />
</td>
You can see here visible attribute binded on displayModel and editMode –and how the span or the input are visible either way.

Same for the checkbox and the select. Because of the MVVM (in this case, knockout) any changes on the data ( name, active, changing department) will be binded back to the array of employees in the javascript MVVM model
Edit Mode –add new employee
When you press add a new employee is generated – the number 3:

It is easy – the Add button calls the same function addEmp that we use to push existing employees:
1 2 3 4 5 6 7 | function BeginAdd(){
model.addEmp(0, '' ,0, true );
model.edit( true );
}
|
So a new employee is added to the array of employees – and the employees table is displaying the added employee . Do you like MVVM now ? 
Edit Mode –delete existing employee
The delete button have this code:
<td><button data-bind="click: $root.removeEmp,visible:editMode">Delete</button></td>
It is clear visible just when editMode is true. And the removeEmp removes the current employee from array, but having the id ( if not 0 – means new) put into a string that contains the ids of deletedEmployeesa:
01 02 03 04 05 06 07 08 09 10 11 | self.removeEmp = function (emp) {
var id=emp.IdEmployee();
if (id != 0)
self.deletedItemsId += id;
self.employees.remove(emp);
};
|
And the employees table is removing the row for the employee . Do you like MVVM now ? 
Edit Mode –send modifications and client validation
On the server side, the parameters of the action that receives the data is simple:
[HttpPost]
1 2 3 | [HttpPost]
public JsonResult SaveEmployees(ListEmployeesViewModel e, string deletedItems)
|
I will explain the 2 arguments. For the first, remember ListEmployeesViewModel from the beginning ? It contains the list of employees and we will post that:
1 2 3 4 5 | public class ListEmployeesViewModel
{
public employeeList AllEmployees { get ; set ; }
|
The second argument is the string that contains the id’s of deletedEmployees.
Now to transmit those from javascript array of employees.
Being a programmer, I like code-reuse. So why not create a function that iterates through an array( of employees), get all properties ( eliminating non-relevant, such as nr, editMode, displayModel and others) and compose the data in the MVC style(http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/ )
First, we need reflection in javascript:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | var refProps= function (obj, exclude , recognizeFunction) {
var properties = [];
for ( var prop in obj) {
if (exclude){
if (exclude(prop))
continue ;
}
var excludeProp = true ;
var t = ( typeof obj[prop]).toLowerCase();
if (t == 'number' || t == 'string' || t == 'boolean' ) {
excludeProp= false ;
}
if (excludeProp){
if (recognizeFunction){
if (t == 'function' ){
if (recognizeFunction(t))
excludeProp= false ;
}
};
}
if (!excludeProp)
properties.push(prop);
};
return properties;
}
|
Fast explanation of parameters:
- obj is the object in javascript that I need all properties that are number, string, or boolean.
- I need to remove some properties(nr,editMode, displayMode) that are relevant in javascript – but not on the server side – so I have put an exclude function( you can put null)
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | function exclude(prop){
switch (prop){
case "nr" :
return true ;
case "deptName" :
return true ;
case "editMode" :
return true ;
case "displayMode" :
return true ;
default :
return false ;
}
|
- Also, knockout make a special ko.observable function
1 | self.NameEmployee = ko.observable(name);
|
– so I need to recognize those functions – and the function is(surprise!) ko.observable
Now saving the array is again re-usable:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | function saveArray(itemsArray, prefix, excludeProp,recognizeFunction,validateProp){
var l = itemsArray.length ;
if (l == 0){
return "" ;
}
var propNames = refProps(itemsArray[0],excludeProp,recognizeFunction);
var nr = 0 ;
var strData= "" ;
for ( var i = 0; i < l; i++) {
var objToSave= itemsArray[i];
for ( var j = 0; j < propNames.length; j++) {
var nameProp = propNames[j];
var val =objToSave[nameProp] ;
var t = ( typeof val).toLowerCase();
if (t == 'function' ){
val = objToSave[nameProp]();
}
if (validateProp) {
if (!validateProp(nameProp,val, objToSave, i)) {
return "" ;
}
}
strData += "&" + prefix+ "[" + nr + "]." + nameProp;
strData += "=" + val;
}
nr++;
}
return strData;
}
|
The itemsArray parameter is the items array that you want to save ( in my case, the employees).
The new function is validateProp – you can pass null – but this is an implementation that take into consideration that the employee should not have the name empty and the user must select something from the department list:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | function validateProperty(propName, value, item, number){
switch (propName){
case "NameEmployee" :
if (value == "" ){
window.alert( "please enter employee name for row number " + (number+1) );
return false ;
}
return true ;
case "iddepartament" :
if (value === undefined || value == 0){
window.alert( "please select a department for row number " + (number+1) );
return false ;
}
return true ;
default :
return true ;
}
}
|
After those 2 re-usable functions( saveArray and refProps ) the code for save is pretty simple:
We obtain the values for employees using saveArray
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 | self.save = function () {
var itemsArray = self.employees();
var strData = saveArray(itemsArray, "AllEmployees" ,exclude, ko.observable,validateProperty);
if (strData == "" )
{
return ;
}
strData= "deletedItems=" +self.deletedItemsId + strData;
window.alert( "saving:" + strData);
|
and post to the server.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | $.ajax({
type: "POST" ,
url: '@Url.Content("~/Home/SaveEmployees")' ,
data: strData ,
datatype: "JSON" ,
var dels=[];
var idExisting= ';' ;
$.each(self.employees(), function (index,emp) {
if (emp.IdEmployee() == 0 )
dels.push(emp);
else
idExisting += emp.IdEmployee()+ ";" ;
});
$.each(dels, function (index,emp) {
self.removeEmp(emp);
});
window.alert( 'add new ones' );
$.each(returndata.emps, function (index,emp) {
var id=emp.IdEmployee;
if (idExisting.indexOf( ";" + id+ ";" ) == -1){
self.addEmp(emp.IdEmployee ,emp.NameEmployee, emp.iddepartament,emp.Active);
}
});
|
Also, for Antiforgery token I have used this code
1 2 3 4 5 | var aft= $( 'input[name="__RequestVerificationToken"]' );
if (aft.length){
strData += "&__RequestVerificationToken=" + aft.val();
}
|
Well, that was it !
Summary:
We have had an javascript array of employees to edit and send data at once . We have make the POST as for ASP.NET MVC rules. You can re-use the refProps javascript function( that gives you the name of the properties of an object – in our case, employee) and saveArray javascript function – that serialize an javascript array to a recognizable ASP.NET MVC idiom
As always, you can find source code at https://github.com/ignatandrei/JavaScriptAndMVVMandMVC/ and you can view online at http://mvvmjavascriptmvc.apphb.com/
Homework for you:
( fork on github and send me the solution via github)
1. Modify the nr ( the employee order number) such as , when deleting or adding a new employee, the numbers are in good order – not 1 and 3 like in the picture

2. Add a hiredate to the employee . Ensure you transmit the date(Hint: Modify the refProps )
LaterEdit:
Hintea Dan Alexandru made a simple application to show me that a simple json.stringify it is enough for MVC to do this magic.
More , it shows directly in the MVVM model a toDTO that is simplier to use( however, the validation part remains to do)
Source code at https://github.com/hinteadan/MvcAjaxSample/#!