16.3. Data Binding and Data Source Controls

 < Day Day Up > 

Data binding enables the contents of a control to be populated by data from a designated data source. Technically speaking, the data source is any collection of data that implements the IEnumerable interface. In simple cases, the source may be an object such as an Array, ArrayList, Hashtable, or SortedList. More often, the data comes from an ADO.NET DataTable, DataSet, or IDataReader object. The control may bind directly to one of these objects, or indirectly, using the special data source controls introduced with ASP.NET 2.0.

Binding to a DataReader

The data reader provides a forward-only, read-only resultset that is the most efficient way to present data. It is generated by issuing the ExecuteReader method of the IDbCommand object. A control binds to the results by setting its DataSource property to the data reader object and executing its DataBind method.

The example in Listing 16-6 illustrates how a data reader is used to populate a ListBox with movie titles from the Films database (described in Chapter 10). The values displayed in the ListBox are based on the value assigned to the DataTextField property in this case, the Movie_Title column in the movies table. The DataValueField property specifies an additional column value that is assigned to each item in the ListBox. When an item is selected, this latter value is returned by the SelectedValue property.

Listing 16-6. Data Binding a List Box to a Data Reader
 <%@ Page Language="C#" %> <%@Import namespace="System.Data.SqlClient" %> <%@Import namespace="System.Data" %> <html> <body> <head><TITLE>Bind Films data to a ListBox</TITLE> <script  runat="Server">    void Page_Load(object sender, EventArgs e) {       if(!this.IsPostBack) {         getMovies();       }    }    private void getMovies()    {       string cnstr=GetConnString(); // Get a connection string       SqlConnection conn = new SqlConnection(cnstr);       IDataReader rdr=null;       IDbCommand cmd = new SqlCommand();       cmd.Connection= conn;       conn.Open();       cmd.Connection=conn;       cmd.CommandText="SELECT movie_id, movie_title FROM movies           ORDER BY AFIRank";       conn.Open();       rdr = cmd.ExecuteReader();       // Bind DataReader to ListBox       ListBoxMovie.DataSource = rdr;       ListBoxMovie.DataBind();       conn.Close();       rdr.Close();    }    </script>    </head>    <FORM NAME="FORM1" runat=server>    <asp:ListBox              dataValueField = "movie_ID"       dataTextField  = "movie_title"       AppendDataBoundItems=true       Rows="10"       BackColor=#efefe4       font-size=9pt       runat="server" >     <asp:ListItem Value=-1 Text="Select Movie" />    </asp:ListBox> </FORM> </body> </html> 

Observe the presence of the AppendDataBoundItems property in the ListBox declaration. This property, a new feature added by ASP.NET 2.0, provides a way to specify whether data binding should overwrite any preexisting items in a list control. This is particularly useful for placing an entry in a list that precedes the actual data. In the preceding example, the ListBox declaration includes a ListItem that causes Select Movie to be placed in it first row.

Binding to a DataSet

It is often preferable to bind a server control to a data reader, rather than to a DataSet. To understand why, let's compare the two (see Figure 16-11). The data reader connects to a table and streams data into the control when the DataBind method is called. A data set, on the other hand, is a cache in memory that is filled with the resultset when the DataAdapter.Fill method is invoked. Its contents are then copied into the control when the control's DataBind method is called. In a WinForms application, the data set remains available to the application until it is closed; in a Web application, the data set disappears after a reply is sent to the browser. As we discuss in the next chapter, it can be saved as a Session variable, but this requires memory and can lead to scalability problems.

Figure 16-11. DataReader versus DataSet as a control's DataSource


There are a couple of situations in which using a DataSet makes sense. One is when multiple controls are bound to the contents of a DataSet. In this code segment, a data set is built that contains a list of all the movies in a table. Two ListBox controls are then populated with different views of the data. One ListBox contains movies produced prior to 1951, and the other contains those produced on or after that year. The advantage of the DataSet in this case is that only one query is applied against the database.

 string sql ="SELECT movie_id, movie_title,movie_year FROM movies       ORDER BY movie_year"; SqlDataAdapter da = new SqlDataAdapter(sql,conn); DataSet ds = new DataSet(); da.Fill(ds,"Movies");  // DataSet and DataTable DataView dview = new DataView(ds.Tables["Movies"]); dview.RowFilter = "movie_year < 1951"; // List box containing movies before 1951 ListBoxMovie.DataSource= dview; ListBoxMovie.DataBind(); // List box containing movies produced after 1950 dview.RowFilter = "vendor_name > 1950"; ListBoxMovie2.DataSource= dview; ListBoxMovie2.DataBind(); 

A DataSet is also useful when the Web application is designed as a three-tier Web site in which the presentation layer accesses a database through an intermediate data access layer. The data access layer contains a method or methods that return a DataSet in response to the call.

Let's look at how the .aspx file in Listing 16-6 can be converted from its current two-tier structure to a three-tier design. The first step is to remove the getMovies method and place it in a separate assembly. In the following code, the method is part of the DataMethods class and rewritten to return a data set containing the vendor data. This code is compiled into a DLL file and placed in the bin subdirectory below the Web page.

 // datalayer.dll   place in \bin subdirectory below application using System.Data.SqlClient; using System.Data; namespace myUtil{    public class DataMethods{       public DataSet getMovies(){         string cnstr= GetConnString(); // Get a connection string          SqlConnection conn = new SqlConnection(cnstr);          IDbCommand cmd = new SqlCommand();          cmd.Connection= conn;          string sql="SELECT movie_id, movie_title FROM                movies ORDER BY AFIRank";          SqlDataAdapter da = new SqlDataAdapter(sql,conn);          DataSet ds = new DataSet();          da.Fill(ds,"Movies");          return (ds);       }    } } 

The code changes in the .aspx file are minimal. An @Import directive is added so that the namespace in datalayer.dll can be accessed.

 <%@Import namespace="myUtil" %> 

The getMovies call is replaced with the following:

 if(!this.IsPostBack) {    DataMethods dm = new DataMethods();    DataSet ds = dm.getMovies();    ListBoxMovie.DataSource = ds;    ListBoxMovie.DataBind(); } 

The use of a data presentation layer promotes code reusability, hides the messy ADO.NET connection details, and results in cleaner code.

DataSource Controls

As we have seen, ASP.NET makes it easy to bind a control to data by simply setting the control's DataSource property to the collection of data it is to display. However, it is still up to the developer to assemble the collection of data. For example, using the data reader as a data source requires the following pattern of operations:

1.

Create a data connection.

2.

Create a Command object.

3.

Build a query and use the Command object to retrieve data into a data reader.

Data source controls encapsulate the functionality required to perform these operations eliminating the need for coding by the developer. The data-bound control is no longer bound to the data collection, but to a data source control. To illustrate, Figure 16-12 shows how a grid can be populated by binding it to a data reader or a SqlDataSource control.

Figure 16-12. Comparison of data binding using ADO.NET code versus DataSource control


Data controls are not limited to database access. In fact, ASP.NET 2.0 supports data source controls that attach to six types of data:

  • AccessDataSource. Binds to a Microsoft Access database.

  • DataSetDataSource. Binds to non-hierarchical XML data.

  • ObjectDataSource. Binds to data through custom classes implemented in a data access layer.

  • SiteMapdataSource. Binds to XML site maps.

  • SqlDataSource. Binds to a SQL database.

  • XmlDataSource. Binds to XML documents.

We'll look at the SqlDataSource, ObjectDataSource, and XmlDataSource controls in this section.

SqlDataSource Control

This control represents a connection to a relational data store, such as SQL Server, DB2, or Oracle. It requires a .NET managed data provider with the capability to return a SQL resultset.

The SqlDataSource control is declared using standard Web control syntax.

Control Declaration:

 <asp:sqldatasource  runat="server" docEmphasis">controlID" 

Properties:

ConnectionString

Connection string to access database.

ProviderName

Managed provider. Default is SqlClient.

DataSourceMode

Controls how the select command retrieves data.

Is a SqlDataSourceMode enumeration: DataSet or DataReader. Default is DataSet.

EnableCaching

True or false. Default is false. Can only be used if DataSourceMode is DataSet.

CacheDuration

How long the contents of the data source aremaintained in memory. Value is in seconds.

SelectCommand

SQL statement that retrieves data from associated data store.

DeleteCommand

SQL statement to delete row(s) from data store.

InsertCommand

SQL statement to insert row(s) into data store.

UpdateCommand

SQL statement to update row(s) in data store.


The four command properties are strings that contain either a SQL command or the name of a stored procedure (if the database supports it) to be executed. Each command can contain parameters whose values are defined by an associated collection of parameters. In an upcoming example, we'll see how the SelectParameters collection is used with SelectCommand. Before that, let's look at how the SqlDataControl is used to populate a Web control.

As in our earlier example, Listing 16-7 fills a ListBox with the name of movies from the Films database. However, in place of raw ADO.NET coding, it defines a data source control and assigns to its SelectCommand property a SQL select string that retrieves a list of movies from the database. A ListBox control is declared with its DataSourceID property set to the ID of the data source control. When the page is loaded, the list control is populated with the resultset.

Listing 16-7. Binding a ListBox to a SqlDataSource Control
 <%@ Page Language="C#"  %> <%@Import namespace="System.Data.SqlClient" %> <%@Import namespace="System.Data" %> <HTML> <HEAD><TITLE>Using a DataSource Control</TITLE> </HEAD> <body> <form  runat="server">    <asp:sqldatasource runat="server"        connectionstring="SERVER=(local);DATABASE=FILMS;       Integrated Security=SSPI; "       providername = "System.Data.SqlClient"       selectCommand= "SELECT movie_ID, movie_Title FROM movies                         ORDER BY AFIRank" >    </asp:sqldatasource>    <table border=0>    <tr><td>    <asp:ListBox runat="server"        dataSourceid   = "SqlDataSource1"       dataValueField = "movie_ID"       dataTtextField = "movie_Title" />    </td></tr>    </table> </form> </body> </html> 

Let's extend this example so that when a movie is selected from the list, its cast members are displayed. To do this, we add a GridView, as shown in Figure 16-13.

Figure 16-13. Using data source controls to depict a parent-child relationship


The data for the GridView also comes from a new data source control. The purpose of this control is to dynamically retrieve a list of actors for any movie selected in the ListBox. The challenge is to identify the movie selected and to specify it in the query. Here's how it's done.

The query assigned to the SelectCommand property contains a parameter (@movieID) that serves as a placeholder for the actual movie ID. Within the data source control is another control, ControlParameter, that has the same name as the parameter in our query. It links the data source control to the ListBox via two properties: ControlID, which specifies the ListBox ID, and PropertyName, which specifies the value to assign to the query parameter. When an item in the ListBox is selected, ASP.NET replaces the parameter with the current SelectedValue of ListBoxMovie (which is a movie ID) and executes the query to retrieve the actor data.

 <asp:SqlDataSource  RunAt="server"    connectionstring="SERVER=(local);DATABASE=FILMS;       Integrated Security=SSPI; "    SelectCommand= "SELECT actor_first, actor_last, actor_sex FROM       actor_movie LEFT JOIN actors ON actor_movie.actor_ID=       actors.actor_ID WHERE movie_ID=@movieID">       <SelectParameters>          <asp:ControlParameter Name="movieID"             ControlID="ListBoxMovie"             PropertyName="SelectedValue"          </asp:ControlParameter>       </SelectParameters> </asp:SqlDataSource> 

The GridView control contains three columns that are bound to the data source control:

 <asp:GridView  DataSource    Width="100%" runat="server" AutoGenerateColumns="false"    SelectedIndex="0" AutoGenerateSelectButton="true" >       <Columns>          <asp:BoundField HeaderText="First Name"               DataField="actor_first" />          <asp:BoundField HeaderText="Last Name"                  DataField="actor_last" />          <asp:BoundField HeaderText="Sex"                  DataField="actor_sex" />       </Columns> </asp:GridView> 

Core Note

In addition to the ControlParameter that specifies the control from which a query's parameter value comes, ASP.NET recognizes five other parameter sources: CookieParameter, FormParameter, ProfileParameter, SessionParameter, and QueryStringParameter.


ObjectDataSource Control

The ObjectDataSource is used when data is retrieved through a data access layer, rather than directly from the database. To demonstrate, recall the three-tier structure we created earlier by placing the getMovies method in a separate assembly. An ObjectDataSource control can be declared to access this method by setting its typename field to the class containing the method and its selectmethod field to the name of the method.

 <asp:objectdatasource        runat="server"    typename="myUtil.DataMethods"    selectmethod="getMovies"> </asp:objectdatasource> 

This could be used to populate the ListBox control in Listing 16-7 by replacing the SqlDataSource control with the ObjectDataSource control and resetting DataSourceID to ObjectDataSource1 in the ListBox declaration.

It is also worth noting that an ObjectDataSource can be used to fetch data from a Web Service. Because Web Services (described in Chapter 18) are nothing more than classes that expose remotely accessible methods, the typename and selectmethod properties can be used to refer to the class and method as if they were in a local assembly.

XmlDataSource Control

The XmlDataSource control is likely to be the most popular of the data source controls. It reads XML data from a local file or a stream transmitted across a network. It's particularly useful for handling the XML formats that are becoming standards for exchanging information across the Internet. To illustrate, we'll create an example that uses the control to read data in the increasingly popular RSS format.

RSS, which stands for Really Simple Syndication, is an XML formatting standard designed originally for news feeds. However, it is now used as a generic way for Web sites to periodically publish information feeds that can be picked up by RSS readers. It not only provides an easy way to distribute data, but the simple format makes it easy for the recipient to determine when any updates have occurred. Because the data is sent as an XML stream, the XmlDataSource control can play the role of a simple RSS reader. As an example, we pair it with a DataList control to capture and display a sample RSS feed from the BBC news network (see Figure 16-14).

Figure 16-14. Display RSS feed using XmlDataSource and DataList controls


The underlying XML conforms to the RSS standard (several versions are now in use). At the top level is the <rss> element that contains a required version attribute. Subordinate to it is a single <channel> element that contains a description of the channel along with its content. The content is supplied by <item> elements that have three mandatory subelements: <title>, <link>, and <description>. Their purpose should be clear from the portion of the XML feed shown here:

 <rss version="0.91">    <channel>       <title>BBC News | Science/Nature | World Edition</title>       <link>          http://news.bbc.co.uk/go/click/rss/0.91/public/-                /2/hi/science/nature/default.stm       </link>       <description>Updated every minute of every day</description>       <item>          <title>Huge 'star-quake' rocks Milky Way</title>          <description>             Astronomers say they are stunned by the explosive             energy released by a super-dense star on the             far side of our galaxy.          </description>       <link>          http://news.bbc.co.uk/go/click/rss/0.91/public/-                  /2/hi/science/nature/4278005.stm       </link>       </item>       <item>       ... other items go here    </channel> </rss> 

Listing 16-8 shows how the XML is displayed using only a DataList and XmlDataSource control. The XmlDataSource control identifies the data source with the DataFile property. As mentioned, this can be a file or a URL. The purpose of the XPath property is to set a filter for the XML document so that only a subset of the document is returned. In this case, we are interested in only the <item> data.

The DataList control identifies the data source component it is bound to by setting the DataSourceID property to the component's ID XmlDataSource1. The XPathBinder object is used to select items or nodes from the XML document. Its XPath method returns a single node, whereas the XPathSelect method returns an ArrayList of matching values. Both take an XPath expression (see Chapter 10) to identify the desired item.

 <%# XPath("xpath-expression"[, "format"]) %> <%# XPathSelect("xpath-expression") %> 

Listing 16-8. Displaying RSS Feed with a DataList and XmlDataSource Control
 <asp:DataList  Runat="server"    RepeatColumns=1    RepeatDirection="Horizontal"    GridLines="Horizontal"    BorderWidth="1px" BackColor="White" CellPadding="2"    BorderStyle="None" BorderColor="#E7E7FF"    DataSourceID="XmlDataSource1">    <ItemTemplate>       <asp:HyperLink  Runat="server"          Text=<%# XPath("title") %>          NavigateUrl=<%# XPath("link") %>          Target="_blank" Font-Names="Sans-Serif"          Font-Size="X-Small">       </asp:HyperLink><br/>       <i><%# XPath("description")%></i><br /><br />    </ItemTemplate>    <AlternatingItemStyle BackColor="#F7F7F7">    </AlternatingItemStyle>    <ItemStyle ForeColor="#4A3C8C"       Font-Size=9pt BackColor="#E7E7FF">    </ItemStyle>    <HeaderTemplate>BBC RSS Feed: Nature</HeaderTemplate>    <HeaderStyle ForeColor="#F7F7F7"       Font-Bold="True" BackColor="#4A3C8C">    </HeaderStyle> </asp:DataList> <asp:XmlDataSource        Runat="server"    XPath="rss/channel/item"    DataFile=       "http://news.bbc.co.uk/rss/newsonline_world_edition/       science/nature/rss091.xml"> </asp:XmlDataSource> 

By binding a data component to a sophisticated visual data control, we are able to create an application in which all data binding is specified through declarations. This can eliminate the need for code to input data, iterate through it, and parse it into a format that can be displayed. In addition, data components have built-in caching features that improve the efficiency of accessing data and eliminate code-managed caching. We look at caching in the next chapter.

     < Day Day Up > 


    Core C# and  .NET
    Core C# and .NET
    ISBN: 131472275
    EAN: N/A
    Year: 2005
    Pages: 219

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net