Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

ASP.NET MVC Model Binding - Part 2

0.00/5 (No votes)
27 Mar 2011 1  
This article gives the reader detailed understanding on how ASP.NET MVC Model binding works.

Introduction

This article is a continuation to the article ASP.NET MVC Model Binding - Part 1. If you have not already read the link, it is recommended to go through the link. I couldn't continue this article immediately because of my health conditions. 

This article covers the remaining areas of Model Binding, collection binding, object collection binding and using Value Providers.  

Using the Code

The sample provided in this article is developed using VS2008 SP1. It is recommended to use the same version of Visual Studio. For simplicity, the source code in the above provided link (previous link) is updated to have more views. Extra views are added to explain different kinds of model bindings. Here is the full code to download. 

The code contains EmployeeView1 to 5 files. EmployeeView1, EmployeeView2 are explained in the previous article. This article concentrates on EmployeeView3, EmployeeView4, EmployeeView5 views.

Collection Binding

Binding HTML input to a collection is collection Binding. When we run the sample, each page contains links to the next page and previous page, go to the Employee View Model3 page. Below is the screen shot of Employee Model Binding 3.

CollectionBinding.JPG

This page is designed to enter employee skills, employees can have multiple skills like Java, .NET, etc. To make it simple, we are taking here two inputs for skills:

The associated Model for this page is: 

public class EmployeeSkills
    {
        [DisplayName("Employee ID")]
        [Required(ErrorMessage = "ID Required")]
        public int EmpId { get; set; }
        [DisplayName("Employee Skills")]
        public string[] Skills { get; set; }
    }

EmployeeSkills model holds the skills for each employee which is a collection, EmpId is the employee id. 

View page contains the following code:

<%= Html.TextBox("Skills[0]")%>
<%= Html.ValidationMessageFor(model => model.Skills)%>
<%= Html.TextBox("Skills[1]")%>
<%= Html.ValidationMessageFor(model => model.Skills)%>    

Input from first text box will bind to Skills[0], input from second text box will bind to Skills[1] of eSkills object. Below is the action method associated with the above binding. 

public ActionResult SkillsUpdate(EmployeeSkills eSkills)
{
    return View("EmployeeView3");
}		

Object Collection Binding

Binding HTML input to collection of objects is Object collection binding. To explain Object collection binding, access the page Employee View 4 in the sample provided, Below is the screen shot of the page:

ObjectCollectionBinding.JPG

EmployeeView4 View page contains the below code:

<table border="1"><tbody><tr><td>
<div class="editor-label">
                <%= Html.LabelFor(model => model.EmpId) %>
            </div>
            <div class="editor-field">
                <%= Html.TextBox("employee[0].EmpId") %>
                <%= Html.ValidationMessageFor(model => model.EmpId) %>
            </div>
            </td>
            <td>
            <div class="editor-label">
                <%= Html.LabelFor(model => model.EmpName) %>
            </div>
            <div class="editor-field">
                <%= Html.TextBox("employee[0].EmpName") %>
                <%= Html.ValidationMessageFor(model => model.EmpName) %>
            </div>
            </td>
            <td>
            <div class="editor-label">
                <%= Html.LabelFor(model => model.EmpDesignation) %>
            </div>
            <div class="editor-field">
                <%= Html.TextBox("employee[0].EmpDesignation") %>
                <%= Html.ValidationMessageFor(model => model.EmpDesignation) %>
            </div>
            </td>
            <td>
            <div class="editor-label">
                <%= Html.LabelFor(model => model.EmpDepartment) %>
            </div>
            <div class="editor-field">
                <%= Html.TextBox("employee[0].EmpDepartment") %>
                <%= Html.ValidationMessageFor(model => model.EmpDepartment) %>
            </div>
            </td>
            <td>
            <div class="editor-label">
                <%= Html.LabelFor(model => model.EmpSalary) %>
            </div>
            <div class="editor-field">
                <%= Html.TextBox("employee[0].EmpSalary") %>
                <%= Html.ValidationMessageFor(model => model.EmpSalary) %>
            </div>
            
            </td>
            </tr> 
            <tr><td>
            <div class="editor-label">
                <%= Html.LabelFor(model => model.EmpId) %>
            </div>
            <div class="editor-field">
                <%= Html.TextBox("employee[1].EmpId") %>
                <%= Html.ValidationMessageFor(model => model.EmpId) %>
            </div>
            </td>
            <td>
            <div class="editor-label">
                <%= Html.LabelFor(model => model.EmpName) %>
            </div>
            <div class="editor-field">
                <%= Html.TextBox("employee[1].EmpName") %>
                <%= Html.ValidationMessageFor(model => model.EmpName) %>
            </div>
            </td>
            <td>
            <div class="editor-label">
                <%= Html.LabelFor(model => model.EmpDesignation) %>
            </div>
            <div class="editor-field">
                <%= Html.TextBox("employee[1].EmpDesignation") %>
                <%= Html.ValidationMessageFor(model => model.EmpDesignation) %>
            </div>
            </td>
            <td>
            <div class="editor-label">
                <%= Html.LabelFor(model => model.EmpDepartment) %>
            </div>
            <div class="editor-field">
                <%= Html.TextBox("employee[1].EmpDepartment") %>
                <%= Html.ValidationMessageFor(model => model.EmpDepartment) %>
            </div>
            </td>
            <td>
            <div class="editor-label">
                <%= Html.LabelFor(model => model.EmpSalary) %>
            </div>
            <div class="editor-field">
                <%= Html.TextBox("employee[1].EmpSalary") %>
                <%= Html.ValidationMessageFor(model => model.EmpSalary) %>
            </div>
            
            </td>
            </tr> 
        </tbody>
</table>

In the above view page, notice the employee[index].PropertyName. This notation binds the employee[0] object to the first object in the employee object collection, employee[1] to the second object in the employee object collection.

Value entered in the first text box will be bound to the first employee object EmpId as it is associated to employee[0].EmpId in the view page. Below is the action method for the object collection binding, employee is an array of Employee.

[HttpPost]
public ActionResult MultipleObjectCollection(Employee[] employee)
{
    return View("EmployeeView4");
}

Using Value Provider

If default model binder is not good enough for model binding, and when we need more control on model binding, we can take the approach of Value providers, FormCollection is a key value pair of form values passed to the action method, and using the UpdateModel(....) method of controller, and using the value provider we can update the model. ASP.NET MVC provides a method UpdateModel(...) which updates the model with the values supplied by value provider. Below is the code for updating the Model manually using value Provider.

public ActionResult ValueProvider(FormCollection fc)
{
    Employee employee = new Employee();
    if(TryUpdateModel(employee,fc.ToValueProvider())) 
        UpdateModel(employee, fc.ToValueProvider());

    return View("EmployeeView5");
}

This is explained using EmployeeView5 view page. When user submits the page, FormCollection gets all the values of the form submitted.

Disclaimer

This article uses a sample, which is not for direct production deployment. This is to give the reader an idea on how model binding works. It is the reader's individual responsibility to follow the necessary best practices while implementing Model Binding.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here