ASP.NET Today: Data Binding
Last night I've just finished chapter 9 (out of 17) of the first book. Chapter 9 is likely to be the longest chapter (about 80 printed pages and 10+ examples) in the first book. It covers all aspects of data binding, basically three:
- Classic binding as in ASP.NET 1.x
- Data binding expressions (with the improvements brought by ASP.NET 2.0)
- Data source controls
Classic binding consists of binding an IEnumerable object to the DataSource property of a data-bound control. This approach has the drawback of requiring a bit too much code even for relatively simple and common scenarios. It is fully supported in ASP.NET 2.0. Data binding expressions are those familiar <%# ...%> expressions you can declaratively insert in your ASPX files. It is important to note that those expressions are processed only during a data binding operation--an operation triggered by a call to DataBind. Without a call to DataBind, no expression will ever be evaluated. ASP.NET 2.0 introduces a new model of expressions prefixed with $ symbol instead of #. These expressions require a custom processor (a .NET class from ExpressionBuilder) but work outside the data binding boundaries. ASP.NET 2.0 provides a few built-in expression builders for connection strings, app settings, and resources. As a result, the following is valid markup:
<asp:SqlDataSource ...
ConnectionString="<%$ ConnectionStrings:LocalNWind %>"
/>
LocalNWind is the name of a connection string stored in the web.config file.
Finally, data source controls are wrappers around IEnumerable-based collections of data. As controls, they have access to caching and viewstate page services and are designed to intelligently work with certain data-bound controls. The motivation for data source controls is saving some boilerplate code by adding intelligence to data source controls and binding them to data-bound controls instead of plain data. The interaction model defined between new and smarter data-bound controls and data source components does the rest. A control executes an operation on the data source to get data, but also to update data or insert and delete data. Want a quick example? Think of a DataGrid control. When you click to see a new page of data, the control fires the PageIndexChanged event. As a page developer, you need to add a event handler with the same code over and over again. Sort of:
void PageChanged(object sender, PageIndexChangedEventArgs e) {
grid.CurrentPageIndex = e.NewPageIndex;
BindData();
}
BindData is a page-specific piece of code to retrieve data and rebind the control. The first line is always the same. This code has been standardized and incorporated in a data source control. Now, the old DataGrid control will still fire the PageIndexChanged event in case of paging. However, the newer GridView control--the successor to the DataGrid--will instead eat the paging request, set the new page index, and silently ask the underlying data source control to provide fresh data. This is a bit oversimplified, but it's just what happens. The same model is extended to cover all CRUD operations.
All ASP.NET 1.x data-bound controls support data source controls in ASP.NET 2.0 applications but only for SELECT operations. The binding takes place through the new DataSourceID property. DataSourceID and DataSource are mutually exclusive.