Programmatic Model Binding Using UpdateModel()
ASP.NET MVC offers model binding to capture form field values entered
in a view. In many cases model binding to complex types serves the purpose. When
the model type to fill from the values is known at development time, you can
specify a parameter of that type. However, this is not always the case. That is
where programmatic model binding comes handy. Programmatic model binding allows
you to perform model binding at runtime based on some condition or processing
logic.
Consider the following page.

The page captures details about workers doing certain job. The EmployeeID,
FirstName and LastName fields are quite straightforward. The tricky thing is -
depending on the selection in the Worker Type dropdown list you need to bind the
values with two different types. When the Worker Type is Employee you want to
bind the values to Employee object and when the Worker Type is Contract you want
to bind values with ContractWorker object.
In this case the target type is dependent on the selection in the dropdown
list. Obviously, you can't decide at development time as to which type is to be
model bound. Let's see how programmatic model bind can be used in such a
situation.
First of all, create a new ASP.NET MVC project and add two model classes -
Employee and ContractWorker. These classes are shown below:
public class Employee
{
public int EmployeeID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class ContractWorker
{
public int EmployeeID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
In this example, both the classes area almost identical but that's not
necessary. In addition to the properties to be model bound they can contain a
different set of properties as per your requirement.
Index view
Now add a new controller (HomeController) and Index view. Then key-in the
following markup in the Index view.
<h1>Enter Worker Details</h1>
<form action="/home/process" method="post">
<table cellpadding="10" border="1">
<tr>
<td>Employee ID :</td>
<td><input type="text" name="employeeid" /></td>
</tr>
<tr>
<td>First Name :</td>
<td><input type="text" name="firstname" /></td>
</tr>
<tr>
<td>Last Name :</td>
<td><input type="text" name="lastname" /></td>
</tr>
<tr>
<td>Worker Type :</td>
<td>
<select name="workerType">
<option value="E">Employee</option>
<option value="C">Contract Worker</option>
</select>
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Submit" />
</td>
</tr>
</table>
</form>
The Index view consists of a <form> that submits to Process action as
indicated in the action attribute. Although the above markup uses plain HTML
tags, you could have also used HTML helpers.
UpdateModel() method
Now add the Process() action inside the HomeController as shown below:
[HttpPost]
public ActionResult Process(string workerType)
{
if(workerType=="E")
{
Employee emp = new Employee();
this.UpdateModel(emp);
//do something with emp
}
if (workerType == "C")
{
ContractWorker worker = new ContractWorker();
this.UpdateModel(worker);
//do something with worker
}
return View("Index");
}
The Process() action takes a string parameter - workerType. Note that
workerType is name of the dropdownlist on the Index view. This way you get the
selection of Worker Type in the action. Then two if blocks check the workerType
value. If it is E a new object of Employee is created. This object will be
initially empty. To fill various properties of emp object you need to perform
model binding. To accomplish this task UpdateModel() method of the Controller
base class is called. The UpdateModel() method accepts an object and tries to
model bind it with from the Request.QueryString or Request.Form collections.
Similarly, the other if block fills the ContractWorker object.
Once filled, you can use emp and worker objects as per your application's
need.
TryUpdateModel() method
Although our application works as expected there is a catch. Run the
application and enter a string in EmployeeID textbox. The call to UpdateModel()
will throw an exception:

Your code throws this exception because UpdateModel() can't convert
string to integer. You can add try-catch to your code to deal with this kind of
exception but there is an alternative - TryUpdateModel() method.
The TryUpdateModel() method is quite similar to UpdateModel() but it silently
returns true or false instead of throwing an exception. That means
TryUpdateModel() will return true if everything goes well, otherwise it will
return false. So, your job is to simply check this return value instead of
adding try-catch. The following code shows how this can be done.
[HttpPost]
public ActionResult Process(string workerType)
{
bool flag = false;
if(workerType=="E")
{
Employee emp = new Employee();
flag = this.TryUpdateModel(emp);
if (flag)
{
//do something with emp
}
}
if (workerType == "C")
{
ContractWorker worker = new ContractWorker();
flag = this.TryUpdateModel(worker);
if (flag)
{
//do something with worker
}
}
return View("Index");
}
}
As you can see, the return value of TryUpdateModel() is stored in flag
variable. If this flag is true only then application specific processing is
invoked.
If you try to run the application again and enter some string value in
EmplyeeID textbox, this time you won't get any exception. The flag will be
silently set to false.
That's it for now! Keep coding!!