Model Binding is a great feature we use today with Web Forms and MVC. In this article you will learn what are Default Model Binding and Explicit Model Binding in MVC. I will use a few code snippets in this article so that you can understand it quickly.
Let's imagine you are working on views that adds new records (Create) or edits the existing record (Edit), in both cases when the user clicks the Create or Update button all the information (that the user entered into controls) is sent by the HTTP POST method to the server, in other words the views post the values to the controller action. So, we implement a HTTP POST version of controller actions to accept the values. Here is the screenshots:
Everybody knows it.
Do you know, to retrieve those values from the HTTP POST request body we can use any one of the following:
1. Old Tedious Approach (not the official name, I just used it)
2. Default Model Binding (aka DefaultModelBinder)
3. Explicit Model Binding
Let's begin with the first one.
1. Old Tedious Approach
In this approach we pull the values directly from the HTTP POST body one by one, here is an example:
[HttpPost]
public ActionResult Create()
{
var friend = new Friend();
friend.Name = Request.Form["Name"];
friend.Address = Request.Form["Address"];
friend.Mobile = Request.Form["Mobile"];
// so on
}
Can you imagine how tedious it is? I have only shown the code to set the three properties, you could have four or five or more. You need to pull each property value out of the Form collection by name and move those values into Friend properties or use those properties without moving sometimes. Any property that is not of type string will also require a type conversion as well.
So, here the MVC model binding is useful and we can use either a Default Model Binding or an Explicit Model Binding.
2. Default Model Binding
With this, instead of digging into each form's values out of the request one by one, we can simply use a Friend object with Create as a parameter; here's how.
[HttpPost]
public ActionResult Create(Friend friend)
{
if (ModelState.IsValid)
{
db.Friends.Add(friend);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(friend);
}
Now the MVC runtime will use the model binding feature to do the rest. The model binder will inspect the friend and find all the friend properties available for binding. The default model binder can automatically convert and move values from the request into a friend object (the model binder can also create an instance of the object to populate).
For example, when the model binder sees a Friend has a Name property, it looks for a value named "Name" in the HTTP POST request body. Notice the model binder looks "in the request" and not "in the form collection". The model binder uses components known as value providers to search for values in various areas of a request. The model binder can look at route data, the query string (like on Edit view, it accepts an id from the query string), and the form collection, and you can add custom value providers if you so desire.
3. Explicit Model Binding
Model binding implicitly begins to work when you have a controller action with a parameter. However, we can also explicitly invoke the model binding using the UpdateModel and TryUpdateModel methods in the controller.
UpdateModel will throw an exception if something goes wrong during model binding and the model is invalid. Here is what the Create action might look like if you used UpdateModel instead of a controller action with a parameter:
[HttpPost]
public ActionResult Create()
{
var friend = new Friend();
try
{
UpdateModel(friend);
db.Friends.Add(friend);
db.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View(friend);
}
}
TryUpdateModel also invokes model binding, but doesn't throw an exception. TryUpdateModel does return a bool, a value of true if model binding succeeded and the model is valid, and a value of false if something went wrong.
[HttpPost]
public ActionResult Create()
{
var friend = new Friend();
if (TryUpdateModel(friend))
{
db.Friends.Add(friend);
db.SaveChanges();
return RedirectToAction("Index");
}