What are Default Model Binding and Explicit Model Binding in MVC?

Model Binding is a great feature we use today with Web Forms and MVC. In this post you will learn what are Default Model Binding and Explicit Model Binding in MVC. I will use few code snippets in this post so that you can understand it quickly.

Let’s imagine you are working on views that adds new record (Create) or edits the existing record (Edit), in both cases when user clicks the Create or Update button all the information (which user entered in controls) sends by HTTP POST method to the server, in other word views posts the values to the controller action. So, we implement 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 HTTP POST request body we can use any one of the following way:

1. Old Tedious Approach (not official name, I just used it)
2. Default Model Binding (aka DefaultModelBinder)
3. Explicit Model Binding

Let’s begin with first one.

1. Old Tedious Approach

In this approach we pull the values directly from 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 three properties, you could have four or five or more. You have 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 MVC model binding comes in action and we can use either Default Model Binding or Explicit Model Binding.

2. Default Model Binding

With this, instead of digging each form values out of the request one by one, we can simply use 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 MVC runtime will use model binding feature to do the rest. Model binder will inspect the friend and finds 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 different areas of a request. The model binder can look at route data, the query string (like on Edit view, it accepts id from query string), and the form collection, and you can add custom value providers if you so desire.

3. Explicit Model Binding

Model binding implicitly goes to work when you have a controller action with parameter. However, we can also explicitly invoke model binding using the UpdateModel and TryUpdateModel methods in 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 controller action with 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");
    }
    else
    {
        return View(friend);
    }
}

Alternatively, we can check model state any time after model binding occurs to see if model binding succeeded, here is example:

[HttpPost]
public ActionResult Create()
{
    var friend = new Friend();
    TryUpdateModel(friend);
    if (ModelState.IsValid)
    {
        db.Friends.Add(friend);
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    else
    {
        return View(friend);
    }
}

If any errors occurred during model binding, model state will contain the names of the properties that caused failures, the attempted values, and the error messages and will display it on view page. While model state is useful for your own debugging purposes, it’s primarily used to display error messages to the user indicating why their data entry failed.

Hope this helps.

Comments

Post a Comment

Popular posts from this blog

Migrating database from ASP.NET Identity to ASP.NET Core Identity

Customize User's Profile in ASP.NET Identity System