Saturday, 3 December 2016

MVC Part 14

ASP.NET MVC - Model Binding

ASP.NET MVC model binding allows you to map HTTP request data with a model. It is the process of creating .NET objects using the data sent by the browser in an HTTP request. The ASP.NET Web Forms developers who are new to ASP.Net MVC are mostly confused how the values from View get converted to the Model class when it reaches the Action method of the Controller class, so this conversion is done by the Model binder.
Model binding is a well-designed bridge between the HTTP request and the C# action methods. It makes it easy for developers to work with data on forms (views), because POST and GET is automatically transferred into a data model you specify. ASP.NET MVC uses default binders to complete this behind the scene.
Let’s take a look at a simple example in which we add a ‘Create View’ in our project from the last chapter and we will see how we get these values from the View to the EmployeeController action method.
Following is the Create Action method for POST.
// POST: Employee/Create
[HttpPost]
public ActionResult Create(FormCollection collection){
   try{
      // TODO: Add insert logic here
      return RedirectToAction("Index");
   }catch{
      return View();
   }
}
Right-click on the Create Action method and select Add View…
Right-click Create Action
It will display the Add View dialog.
Display Add View Dialog
As you can see in the above screenshot, the default name is already mentioned. Now select Create from the Template dropdown and Employee from the Model class dropdown.
You will see the default code in the Create.cshtml view.
@model MVCSimpleApp.Models.Employee
@{
   Layout = null;
}

<!DOCTYPE html>
<html>
   <head>
      <meta name = "viewport" content = "width = device-width" />
      <title>Create</title>
   </head>
 
   <body>
      @using (Html.BeginForm()){
         @Html.AntiForgeryToken()
         <div class = "form-horizontal">
            <h4>Employee</h4>
            <hr />
            @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    
            <div class = "form-group">
               @Html.LabelFor(model => model.Name, htmlAttributes:
                  new{ @class = "control-label col-md-2" })
      
               <div class = "col-md-10">
                  @Html.EditorFor(model => model.Name, new{ htmlAttributes =
                     new { @class = "form-control" } })
       
                  @Html.ValidationMessageFor(model => model.Name, "",
                     new{ @class = "text-danger" })
               </div>
            </div>
    
            <div class = "form-group">
               @Html.LabelFor(model => model.JoiningDate, htmlAttributes:
                  new{ @class = "control-label col-md-2" })
      
               <div class = "col-md-10">
                  @Html.EditorFor(model => model.JoiningDate, new{ htmlAttributes =
                     new { @class = "form-control" } })
       
                  @Html.ValidationMessageFor(model => model.JoiningDate, "",
                     new { @class = "text-danger" })
               </div>
            </div>
    
            <div class = "form-group">
               @Html.LabelFor(model => model.Age, htmlAttributes:
                  new { @class = "control-label col-md-2" })
      
               <div class = "col-md-10">
                  @Html.EditorFor(model => model.Age, new { htmlAttributes =
                     new { @class = "form-control" } })
       
                  @Html.ValidationMessageFor(model => model.Age, "", new{ @class = "text-danger" })
               </div>
            </div>
    
            <div class = "form-group">
               <div class = "col-md-offset-2 col-md-10">
                  <input type = "submit" value = "Create" class = "btn btn-default"/>
               </div>
            </div>
    
         </div>
      }
  
      <div>
         @Html.ActionLink("Back to List", "Index")
      </div>
  
   </body>
</html>
When the user enters values on Create View then it is available in FormCollection as well as Request.Form. We can use any of these values to populate the employee info from the view.
Let’s use the following code to create the Employee using FormCollection.
// POST: Employee/Create
[HttpPost]
public ActionResult Create(FormCollection collection){
   try {
      Employee emp = new Employee();
      emp.Name = collection["Name"];
      DateTime jDate;
      DateTime.TryParse(collection["DOB"], out jDate);
      emp.JoiningDate = jDate;
      string age = collection["Age"];
      emp.Age = Int32.Parse(age);
      empList.Add(emp);
      return RedirectToAction("Index");
   }catch {
      return View();
   }
}
Run this application and request for this URL http://localhost:63004/Employee/. You will receive the following output.
Localhost Employee Output
Click the ‘Create New’ link on top of the page and it will go to the following view.
Create New Link
Let’s enter data for another employee you want to add.
Another Employee Data
Click on the create button and you will see that the new employee is added in your list.
New Employee Added
In the above example, we are getting all the posted values from the HTML view and then mapping these values to the Employee properties and assigning them one by one.
In this case, we will also be doing the type casting wherever the posted values are not of the same format as of the Model property.
This is also known as manual binding and this type of implementation might not be that bad for simple and small data model. However, if you have huge data models and need a lot of type casting then we can utilize the power and ease-of-use of ASP.NET MVC Model binding.
Let’s take a look at the same example we did for Model binding.
We need to change the parameter of Create Method to accept the Employee Model object rather than FormCollection as shown in the following code.
// POST: Employee/Create
[HttpPost]
public ActionResult Create(Employee emp){
   try{
      empList.Add(emp);
      return RedirectToAction("Index");
   }catch{
      return View();
   }
}
Now the magic of Model Binding depends on the id of HTML variables that are supplying the values.
For our Employee Model, the id of the HTML input fields should be the same as the Property names of the Employee Model and you can see that Visual Studio is using the same property names of the model while creating a view.
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
The mapping will be based on the Property name by default. This is where we will find HTML helper methods very helpful because these helper methods will generate the HTML, which will have proper Names for the Model Binding to work.
Run this application and request for the URL http://localhost:63004/Employee/. You will see the following output.
Request for URL
Let’s click on the Create New link on the top of the page and it will go to the following view.
Click Create New Link
Let’s enter data for another employee that we want to add.
Enter Data Another Employee
Now click the create button and you will see that the new employee is added to your list using the ASP.Net MVC model binding.
MVC Model Binding

No comments:

Post a Comment