Mar
22
2013

Super cool Model Binding functionality in asp.net 4.5

Introduction

There are plenty of new features that has been shipped with Asp.net 4.5 and VS 2012. From Asp.net web form perspective, new model binding feature is a giant change in the way how web forms developers deal with the data binding control.

Data bound controls are major part of a typical web form applications and we as a developer spend lot of time in writing code in different event of controls. Also, it takes lots of learning and practice to create a simple grid with basic functionality like sorting, paging etc.

The new Model binding functionality makes these tasks dead easy so that you as a developer can focus on data and entities.

Article Body

I think, "You cannot appreciate new things unless you know the pain of living without it". So, to showcase the new model binding feature, I will first compare the older way of doing things.

To better understand the code, let me first explain the scenario.

We have a employees table in our demo database which has following columns.

We want to display the all the records from this table using our own GridView control which supports sorting and paging.

How would we do this?

Older way

Let's consider the classic GridView control with paging. Until Asp.net 4.0, to display the data in Grdview, we required gridview tag like this

<asp:GridView ID="gvEmployees" runat="server" 
AllowSorting="true" 
OnSorting="gvEmployees_Sorting">
</asp:GridView>

And to populate the gridview from codebehind, we needed to set the datasource and call DataBind method of gridview

EmpEntities empContext = new EmpEntities();
var employeeList = empContext.Employees;

gvEmployees.DataSource = employeeList.ToList();
gvEmployees.DataBind();

And then, we needed to create separate events of gridview for sorting, paging etc. and again, write a query in these events to get sorted or paged records from database and bind to gridview.

        protected void gvEmployees_Sorting(object sender, GridViewSortEventArgs e)
        {
            EmpEntities empContext = new EmpEntities();
            var employeeList = empContext.Employees.OrderBy(item=>item.First_Name);
            gvEmployees.DataSource = employeeList.ToList();
            gvEmployees.DataBind();
        }

Considering the repetitive and patterned nature of this work, .Net 4.5 has introduced a feature called model binding which takes advantage of System.Linq.IQueryable type.

The new way using model binding (.Net 4.5)

In Asp.net 4.5 you will first create a public method in codebehind which should return IQueryable<type> or IEnumerable<type>

        public IQueryable<Employee> GetEmployees()
        {
            EmpEntities empContext = new EmpEntities();
            IQueryable<Employee> employeeList = empContext.Employees;
            return employeeList;
        }

Now, create a GridView control tag in .aspx page like this

<asp:GridView ID="gvEmployees" ItemType="DataBindingSample.Employee" 
runat="server" 
SelectMethod="GetEmployees">

...

</asp;GridView>

Make sure that this stands true

That's it. Now, run the application and... voila! the gridview is displayed with all the data. Yes, that's correct; you don't need to set the datasource and call databind method etc. It all happens behind the scene.

Now, what if you want to add functionality of sorting and paging to the gridview? It is now matter of a adding two more attributes to gridview control's tag. No event creation and handling is required. Simply add following attributes.

<asp:GridView ID="gvEmployees" runat="server" CellPadding="4"
ItemType="DataBindingSample.Employee" SelectMethod="GetEmployees"
AllowSorting="true" AllowPaging="true" PageSize="5" DataKeyNames="id">

Simply run the page to see paging and sorting in action

Note: If you do not set the DataKeyNames attribute and set AllowPaging true then you will see the error message which reads

"The method 'Skip' is only supported for sorted input in LINQ to Entities. The method 'OrderBy' must be called before the method 'Skip'."

If you see this message, then make sure you have set the DataKeyNames attribute.

Filter data using model binding

With Gridview, it is generally required to provide the functionality of searching records. You will not require handling some search button event and write separate code to search records using separate query and do the binding etc.

We can take advantage of same IQueryable SelectMethod to even filter the records. Let's consider, we have a textbox and a button along with our Employees gridview. Users can enter the first name of the employee who they want to search and click on a button.

To do this, simply add textbox and a button on the aspx page

<p>
     Search by first name 
     <asp:TextBox ID="txtSearch" runat="server"></asp:TextBox> 
     <asp:Button ID="btnSearch" runat="server" Text="Search" />
 </p>

and change the SelectMethod GetEmployees as

public IQueryable<Employee> GetEmployees([System.Web.ModelBinding.Control("txtSearch")] string searchText)
  {
      searchText = searchText == null ? string.Empty : searchText;
      EmpEntities empContext = new EmpEntities();
      IQueryable<Employee> employeeList = empContext.Employees.Where(item=>item.First_Name.Contains(searchText));
      return employeeList;
  }

As it is evident from the above code, we are simply passing value of textbox txtSearch as a parameter to the SelectMethod which is subsequently used to filter records using lambda expression. The attribute System.Web.ModelBinding.Control indicates that the value provider for this parameter is a control on the page.

That means, you can specify the different value providers based on source, from where you want to accept the search parameter.

For example, if you want to filter the result based on value passed in a querystring then, model binding filter will look as

public IQueryable<Employee> GetEmployees([System.Web.ModelBinding.QueryString("EmployeeName")] string strFullName)
{
    ...
}

There are following types of value providers are available in ModelBinding namespace

  • Control
  • Query string
  • View data
  • Session data
  • Cookies
  • Form data
  • View state
  • Profile data

Note: You do not need to create a event for button click. On every postback, ModelBinding mechanism detects if there is any change in the source of value of provider (say textbox) if yes, It automatically binds the filtered data to grid control. A simple button without event also causes post back which is sufficient to rebind the gridview with filtered records

Edit and Update the records

The more advanced (and obvious) requirement in a typical gridview is to allow users to edit/update and delete the records. Without model binding, we will have to create and implement Row_Updating event in which values are read from different cells of the row and database row is updated using those values.

This approach requires lot of custom code and reading values of gridview cells using FindControl etc.

ModelBinding provides an extremely easy way to update/delete the records directly. Continuing with our earlier example, let's add update functionality in the Employees data gridview

In the gridview tag, add a attribute named "UpdateMethod" and assign an function name to it. Then, add another attribute AutoGenerateEditButton and set its value to true.

<asp:GridView ID="gvEmployees" ItemType="DataBindingSample.Employee" 
runat="server" 
SelectMethod="GetEmployees" UpdateMethod="UpdateEmployeeData" AutoGenerateEditButton="true" >

Here, we added an UpdateMethod and assigned it a name "UpdateEmployeeData". Now, add an method with the same name in the codebehind.

public void UpdateEmployeeData(int id)
  {
      Employee empItem = null;
      EmpEntities empContext = new EmpEntities();
      empItem = empContext.Employees.Find(id);
      TryUpdateModel(empItem);
      if (ModelState.IsValid)
      {
          empContext.SaveChanges();
      }
  }

Note: The function accepts the id parameter which is passed from DataKeyName column value of GridView

In the function, first the reference to entity record is identified based on id parameter. The referenced entity is stored in the Employee modal object.

The modal object is passed to TruUpdateModal method which model bind the data control values (in this case, GridView) and once the values are automatically bind to modal object, you simply need to call SaveChanges method on the DBContext.

Finally, run the page to see update operation in action.

The GridView would have a edit button

And once you click on edit button, it will display pre populated textfield in all the gridview cells in that row. User can now update the value in any cell and click on a update button... and the updated values are stored in the database and gridview is refreshed to display the updated values.

Similar to edit functionality, you can easily implement the delete feature in GridView using ModelBinding. I will leave that to you :)

The code I used for this demonstration can downloaded here

ModelBinding.zip (9.39 mb) 

Conclusion

Among many new features introduced as part of Asp.net 4.5, Model binding is on of the most important feature which is extremely useful and I believe would change the way how data controls were generally managed in web form applications.

I will try to explore model binding in more detail in some of my upcoming articles. Thanks for visiting!

About Me

You are visiting personal website of Kedar (KK)

Please go here to know more about me

Disclaimer

The opinions expressed here represent my own and not those of my past or present employers.

The concept/code provided on this site may not work as described. If you are using any code provided on this site. Then, please test it thoroughly. I shall not be responsible for any issues arising in the code. 

Month List