Recipe 6.4 Preserving Information Across Multiple Requests for a Page

     

Recipe 6.4 Preserving Information Across Multiple Requests for a Page

6.4.1 Problem

You have a page that contains complex object information you need to preserve between requests for the page. The data contains information you do not want to be readable in the rendered HTML, and you do not want to use a database to preserve the information.

6.4.2 Solution

Use the ViewState property of the Page object to store the data. You can then access the data when the page is submitted back to the server.

In the code-behind class for the page, use the .NET language of your choice to add all the code necessary to handle the storage and recovery of the object data to and from the ViewState .

In a separate class file, use the .NET language of your choice to define the container in which you will store the data in the ViewState .

The application that illustrates this solution is shown in Examples Example 6-14 through Example 6-18. Example 6-14 shows the .aspx file. Example 6-15 and Example 6-16 show the VB and C# code-behind files. Examples Example 6-17 and Example 6-18 show the VB and C# data service class. Figure 6-4 shows the form produced by the application.

Figure 6-4. Maintaining page state with ViewState
figs/ancb_0604.gif

6.4.3 Discussion

The ViewState is an object similar to the Application and Session objects discussed in the previous recipes; however, its method of data storage is quite different. Unlike the Application and Session objects, which are stored in server memory, the ViewState is stored in a hidden form field within the HTML sent to the browser. This property lets you store page state information directly in a page and then retrieve it, without using server resources, when the page is posted back to the server. This technique does result, however, in additional data being transmitted to and from the server.

ASP.NET uses the ViewState to store state information for the server controls on your form so it can rehydrate (or deserialize the data for) the controls upon submittal of the page to the server. You can use the ViewState for storing page state data in your application as well. What we mean by "page state data" in this context is user -specific state values that aren't stored by a control. Values are tracked in ViewState similarly to how they are tracked in Session (described in Recipe 6.2) and Cache (described in Recipe 13.5).

A simple example of when you might want to use ViewState in this way is when you want to display a list of items in a DataGrid , and each user wants to sort the DataGrid 's columns differently. In this context, the sort order is a small piece of user-specific page state that you want to maintain when the page is submitted back to the server. ViewState is a fine place to store this type of value, and the Visual Studio .NET help files are replete with examples of this sort.

The example we've written to illustrate this solution is both a bit more ambitious than the aforementioned example and fairly long, but worth the effort. It demonstrates not only the ability to store complex objects in the ViewState for tracking state information between page submittals but also how to emulate the two-way data binding that is available in Windows applications developed with .NET but not available to ASP.NET applications. When used together, these two concepts provide the ability to use many of the features of ASP.NET, which can greatly simplify the code required to develop an application.

The .aspx file, shown in Example 6-14, is typical of a page containing a data-bound DataGrid (see Chapter 1). The one difference in this example is the use of constants from the data service class to define the fields bound to the columns in the DataGrid . The constants are described later, during the discussion of the data service class.

In Example 6-14, the following changes are required to use the .aspx file with C#:

  • Change the namespace in the imports statement to ASPNetCookbook.CSExamples .

  • In each DataBinder.Eval statement, remove the VB line continuation characters and replace CH06TestDataVB with CH06TestDataCS .


You'll find all code that handles the persistence and recovery of the object data you store in the ViewState in the code-behind, shown in Example 6-15 (VB) and Example 6-16 (C#).

The data service class, shown in Example 6-17 (VB) and Example 6-18 (C#), provides a container for persisting the data in the ViewState . (The data service class is described at the end of this example.)

Because you will want to access the object persisted in the ViewState from multiple places in your code, we've defined a constant in the code-behind, VS_TEST_DATA , to define the name of the variable used to access the object in the ViewState . With this approach, you avoid the problems that arise when you hardcode a variable name throughout your code.

In the Page_Load method of the code-behind, an instance of the data service class is created by calling its constructor. The new object is then passed to the bindData method to bind the data in the object to the DataGrid in the .aspx file.

It is important to create the new object only when the page is originally rendered. Creating it on subsequent postbacks would result in loss of the data entered by the user.


The bindData method performs two operations. First, it binds the data in the passed testData object to the DataGrid . This is done by setting the DataSource to the table in the DataSet of the passed object and calling the BindData method of the DataGrid . In addition, the DataKeyField is set to the field in the table that contains the primary key data. This provides the unique identifier for each row of test data in the rendered DataGrid and is needed to update the data submitted back to the server. The bindData method then persists the passed object to the ViewState . This causes the testData object to be serialized to a string and placed in the ViewState when the page is rendered.

When a page is rendered and sent to the client browser, all objects created in the code-behind are destroyed . This means that the testData object no longer exists after the page is rendered, unless you have persisted it. This is where data binding in web applications differs greatly from data binding in Windows applications. In a Windows application, the underlying DataSet , DataTable , or other data container that is bound to the controls on the Windows form continues to exist and remains connected to the bound controls. Any changes made to the data in the bound controls are updated in the underlying data container, making updates to the original data source extremely simple. In web forms, the connection to the underlying data container is broken when the page is rendered. Emulating the two-way binding and simple data updates available in Windows applications requires a bit of additional work, but it can be well worth the effort.


When the user clicks the Update button, the form is submitted back to the server. ASP.NET takes care of updating the DataGrid server control with the data posted back to the server. However, the underlying data container (the testData object in this example) is not recreated by ASP.NET. Therefore, the testData object is rehydrated from the ViewState in the Update button click event.

After rehydrating the testData object, the contents of the object need to be updated with the current data in the DataGrid . This is done by iterating through the rows in the grid, extracting the individual data values, and then updating the contents of the testData object.

For each row, the primary key value is obtained from the DataKeys collection for the current item. This is possible because the DataKeyField was set to the column containing the primary key when the DataGrid was originally bound.

Next, a reference is obtained to the first grade score text box. This is done by using the FindControl method of the current DataGrid item. This is possible because the text boxes defined in the DataGrid have been assigned IDs that are used here to perform the lookup. After the ID has been retrieved, the first grade score is updated in the testData object with the value in the text box. This process is then repeated for the second grade score text box.

Production code should have validation to ensure only numeric values are entered in the text box. This is best done using validation controls (see Chapter 2) or a custom control that allows only numeric entry as described in Recipe 5.4.


After updating the contents of the object, the update method is called to update the contents of the database with the data in the object, and then the data is again bound to the DataGrid .

The StateTestDataVB class (see Example 6-17 for the VB version and Example 6-18 for the C# version) provides the data services for this example. It encapsulates the data along with the methods for operating on the data. The class is defined with the Serializable attribute to provide the ability to serialize the data in the object created from the class to a string, which can then be stored in the ViewState or another location, such as a database. This string can then be deserialized to rehydrate the original object.

The class is designed to contain a DataSet as the container for the object data. This DataSet also provides the ability to bind a DataGrid or another control directly to the data in the object. To bind to the internal data, two things are required. First, a property (the read-only testData property) must be provided to obtain a reference to the data table that contains the data.

Second, the names of the columns in the data table used for binding must be made available to bind controls to the specific data elements. These are defined as public constants in the class to provide a loose coupling between the code-behind and the data services class. By using the constants, the names of the columns can change without affecting any of the code that uses the StateTestDataVB class.

The constructor for the class queries the database for the test data used in this example and fills the private member mTestData . The only special operation performed is to define the data column that is the primary key for the table in the DataSet . This makes it possible to find a specific row using the primary key value.

If the primary key is not defined for a table in the DataSet , the code would be required either to filter the data in the table using a DataView or to iterate through all of the rows in the data table to find the row of interest. Both of these approaches can cause a significant performance penalty.


Two properties are defined to set the first and second grade scores. Both of these properties perform the same actions but on different columns in the data table. To set a value, the appropriate row must be located. This is done by using the Find method of the row collection with the testID (primary key) value passed to the property. Note that the find operation will only work if a primary key is defined for the table. After finding the row matching the passed testID , the value is set to the passed score.

When all data has been changed, as required in the object, the Update method is called. This method updates the data from the object to the database. It utilizes the functionality in ADO.NET that will, with just a few lines of code, perform all inserts , updates, and deletes required to match the data in the database with the data in the data table. This basically requires four steps:

  1. Open a connection to the database. This is the same process used in the constructor.

  2. Create a new data adapter using the same Select statement used to populate the data table originally.

It is important that all of the columns currently contained in the data table be included in the Select statement. For this reason it is good to define the Select statement as a constant or a private member variable to allow the constructor and Update methods to use the same Select statement, as shown in the following code:

 
figs/vbicon.gif
 da = New OleDbDataAdapter(SELECT_STR, dbConn) 
figs/csharpicon.gif
 da = new OleDbDataAdapter(SELECT_STR, dbConn); 


  1. Create a new command builder with a reference to the data adapter created in Step 2. The command builder will build the appropriate insert, update, and delete commands from the provided Select command.

  2. Call the Update method of the data adapter. This will perform all required inserts, updates, and deletes required to cause the data in the database to match the data in the data table.

The update works because every row in a data table has a status property that indicates if the row in the data table has been modified, added, or deleted. From this status information, the data adapter can determine what actions are required.


This example does not provide the ability to add new tests or delete current tests. You can easily add the functionality to the StateTestDataVB class by adding two methods, addTest and deleteTest . Your addTest method needs to be passed the test name, its maximum score, and the scores for first and second grade. With the passed data, it should add a new row to the data table containing the test data. Likewise, your deleteTest method should delete the required row from the data table using the Delete method of the rows collection. The Delete method does not actually delete the row but marks it for deletion when the update is performed.

Although the technique described in this example is extremely powerful and useful, it should be used carefully . Placing a serialized object in the ViewState can significantly increase the size of the information sent to the client browser, and, because the ViewState information is stored in a hidden form field, it is also sent back to the server when the page is submitted. In most cases, this is not a big issue, because an extra few thousand bytes is not a problem. But if you have a very large object, the overhead could be excessive. One way to use this technique with a large object is to store the object in the Session object instead of the ViewState . The trade-off is the server resources and time required to transmit the data to the Session object. Refer to Recipe 6.2 for information on using the Session object.


6.4.4 See Also

Example 6-14. Maintaining page state using the ViewState (.aspx)
 <%@ Page Language="vb" AutoEventWireup="false" Codebehind="CH06ViewStateVB.aspx.vb" Inherits="CH06ViewStateVB" %>  <%@ Import Namespace="ASPNetCookbook.VBExamples" %>  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>ViewState Persistence</title> <link rel="stylesheet" href="css/ASPNetCookbook.css"> </head> <body leftmargin="0" marginheight="0" marginwidth="0" topmargin="0"> <form id="frmStateViewState" method="post" runat="server"> <table width="100%" cellpadding ="0" cellspacing="0" border="0"> <tr> <td align="center"> <img src="images/ASPNETCookbookHeading_blue.gif"> </td> </tr> <tr> <td class="dividerLine"> <img src="images/spacer.gif" height="6" border="0"></td> </tr> </table> <table width="90%" align="center" border="0"> <tr> <td><img src="images/spacer.gif" height="10" border="0"></td> </tr> <tr> <td align="center" class="PageHeading"> Maintaining Page State With The ViewState (VB) </td> </tr> <tr> <td><img src="images/spacer.gif" height="10" border="0"></td> </tr> <tr> <td align="center"> <asp:DataGrid ID="dgScores" Runat ="server" Width="100%" AutoGenerateColumns="False" BorderColor="000080" BorderWidth="2px" HeaderStyle-BackColor="#000080" HeaderStyle-CssClass="TableHeader" ItemStyle-CssClass="TableCellNormal" ItemStyle-BackColor="#FFFFFF" > <Columns> <asp:TemplateColumn HeaderStyle-HorizontalAlign="Center" HeaderText="Test Name"> <ItemTemplate>  <%# DataBinder.Eval(Container.DataItem, _   CH06TestDataVB.TEST_NAME) %>  </ItemTemplate> </asp:TemplateColumn> <asp:TemplateColumn HeaderStyle-HorizontalAlign="Center" ItemStyle-HorizontalAlign="Center" HeaderText="Max Score"> <ItemTemplate>  <%# DataBinder.Eval(Container.DataItem, _   CH06TestDataVB.MAX_SCORE) %>  </ItemTemplate> </asp:TemplateColumn> <asp:TemplateColumn HeaderStyle-HorizontalAlign="Center" ItemStyle-HorizontalAlign="Center" HeaderText="First Grade<br />Passing Score"> <ItemTemplate>  <asp:TextBox id="txtFirstGradeScore" runat="server"   Columns="5"   text='<%# DataBinder.Eval(Container.DataItem, _   CH06TestDataVB.FIRST_GRADE_PASSING_SCORE) %>' />  </ItemTemplate> </asp:TemplateColumn> <asp:TemplateColumn HeaderStyle-HorizontalAlign="Center" ItemStyle-HorizontalAlign="Center" HeaderText="Second Grade<br />Passing Score"> <ItemTemplate>  <asp:TextBox id="txtSecondGradeScore" runat="server"   Columns="5"   text='<%# DataBinder.Eval(Container.DataItem, _   CH06TestDataVB.SECOND_GRADE_PASSING_SCORE) %>' />   </ItemTemplate>  </asp:TemplateColumn> </Columns> </asp:DataGrid> </td> </tr> <tr> <td align="center"> <br /> <asp:ImageButton ID="btnUpdate" Runat="server" ImageUrl="images/buttons/button_update.gif" /> <asp:ImageButton ID="btnCancel" Runat="server" ImageUrl="images/ buttons /button_cancel.gif" /> </td> </tr> </table> </form> </body> </html> 

Example 6-15. Maintaining page state using the ViewState (.vb)
 Option Explicit On Option Strict On '----------------------------------------------------------------------------- ' ' Module Name: CH06ViewStateVB.aspx.vb ' ' Description: This module provides the code behind for ' CH06ViewStateVB.aspx ' '***************************************************************************** Imports Microsoft.VisualBasic Imports System Imports System.Web.UI.WebControls Public Class CH06ViewStateVB Inherits System.Web.UI.Page 'controls on the form Protected dgScores As System.Web.UI.WebControls.DataGrid Protected WithEvents btnUpdate As System.Web.UI.WebControls.ImageButton Protected WithEvents btnCancel As System.Web.UI.WebControls.ImageButton  'the following constant defines the name of the viewstate variable used   'to store the test data object   Private Const VS_TEST_DATA As String = "TestData"  '************************************************************************* ' ' ROUTINE: Page_Load ' ' DESCRIPTION: This routine provides the event handler for the page load ' event. It is responsible for initializing the controls ' on the page. '------------------------------------------------------------------------- Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Dim testData As CH06TestDataVB If (Not Page.IsPostBack( )) Then 'create new test data object and bind to it  testData = New CH06TestDataVB   bindData(testData)  End If End Sub 'Page_Load '************************************************************************* ' ' ROUTINE: btnUpdate_Click ' ' DESCRIPTION: This routine provides the event handler for the update ' button click event event. It is responsible for updating ' the contents of the database with the data from the ' form. '-------------------------------------------------------------------------  Private Sub btnUpdate_Click(ByVal sender As Object, _   ByVal e As System.Web.UI.ImageClickEventArgs) _   Handles btnUpdate.Click   'the following constants define the names of the textboxes in the   'datagrid rows   Const FIRST_GRADE_SCORE_TEXTBOX As String = "txtFirstGradeScore"   Const SECOND_GRADE_SCORE_TEXTBOX As String = "txtSecondGradeScore"   Dim testData As CH06TestDataVB   Dim item As System.Web.UI.WebControls.DataGridItem   Dim txtScore As TextBox   Dim testID As Integer   'make sure page contents are valid   If (Page.IsValid) Then   'rehydrate the test data object from the viewstate   testData = CType(viewstate.Item(VS_TEST_DATA), _   CH06TestDataVB)   'copy the contents of the fields in the datagrid to the test data   'object to emulate the two-way databinding in the Windows world   For Each item In dgScores.Items   'get the testID for the test data in the datagrid row   testID = CInt(dgScores.DataKeys.Item(item.ItemIndex))   'get a reference to the first grade score textbox in the row   txtScore = CType(item.FindControl(FIRST_GRADE_SCORE_TEXTBOX), _   TextBox)   'update the first grade score in the test data object   testData.firstGradeScore(testID) = CInt(txtScore.Text)   'get a reference to the second grade score textbox in the row   txtScore = CType(item.FindControl(SECOND_GRADE_SCORE_TEXTBOX), _   TextBox)   'update the first grade score in the test data object   testData.secondGradeScore(testID) = CInt(txtScore.Text)   Next item   'update the test data in the database   testData.update( )   'rebind the data to the datagrid   bindData(testData)   End If   End Sub 'btnUpdate_Click  '************************************************************************* ' ' ROUTINE: btnCancel_Click ' ' DESCRIPTION: This routine provides the event handler for the cancel ' button click event event. It is responsible for ' cancel the current edits. '------------------------------------------------------------------------- Private Sub btnCancel_Click(ByVal sender As Object, _ ByVal e As System.Web.UI.ImageClickEventArgs) _ Handles btnCancel.Click 'perform the actions required to cancel the edits End Sub 'btnCancel_Click '***************************************************************************** ' ' ROUTINE: bindData ' ' DESCRIPTION: This routine binds the data in the passed object to the ' datagrid then persists the object in the viewstate '----------------------------------------------------------------------------- Private Sub bindData(ByVal testData As CH06TestDataVB) 'bind the test data to the datagrid dgScores.DataSource = testData.testData( ) dgScores.DataKeyField = testData.TEST_DATA_ID dgScores.DataBind( )  'save the test data object in the view state   viewstate.Add(VS_TEST_DATA, _   testData)  End Sub 'bindData End Class 'CH06ViewStateVB 

Example 6-16. Maintaining page state using the ViewState (.cs)
 //---------------------------------------------------------------------------- // // Module Name: CH06ViewStateCS.ascx.cs // // Description: This module provides the code behind for // CH06ViewStateCS.ascx // //**************************************************************************** using System; using System.Configuration; using System.Data; using System.Web.UI; using System.Web.UI.WebControls; namespace ASPNetCookbook.CSExamples { public class CH06ViewStateCS : System.Web.UI.Page { // controls on the form protected System.Web.UI.WebControls.DataGrid dgScores; protected System.Web.UI.WebControls.ImageButton btnUpdate; protected System.Web.UI.WebControls.ImageButton btnCancel;  // the following constant defines the name of the viewstate variable used   // to store the test data object   private const String VS_TEST_DATA = "TestData";  //************************************************************************ // // ROUTINE: Page_Load // // DESCRIPTION: This routine provides the event handler for the page // load event. It is responsible for initializing the // controls on the page. //------------------------------------------------------------------------ private void Page_Load(object sender, System.EventArgs e) { CH06TestDataCS testData = null; // wire the update and cancel button click events this.btnUpdate.Click += new ImageClickEventHandler(this.btnUpdate_Click); this.btnCancel.Click += new ImageClickEventHandler(this.btnCancel_Click); if (!Page.IsPostBack) {  // create new test data object and bind to it   testData = new CH06TestDataCS( );   bindData(testData);  } } // Page_Load //************************************************************************ // // ROUTINE: btnUpdate_Click // // DESCRIPTION: This routine provides the event handler for the update // button click event event. It is responsible for // updating the contents of the database with the data // from the form. //------------------------------------------------------------------------  private void btnUpdate_Click(Object sender,   System.Web.UI.ImageClickEventArgs e)   {   // the following constants define the names of the textboxes in the   // datagrid rows   const String FIRST_GRADE_SCORE_TEXTBOX = "txtFirstGradeScore";   const string SECOND_GRADE_SCORE_TEXTBOX = "txtSecondGradeScore";   CH06TestDataCS testData = null;   TextBox txtScore = null;   int testID;   // make sure page contents are valid   if (Page.IsValid)   {   // rehydrate the test data object from the viewstate   testData = (CH06TestDataCS)(ViewState[VS_TEST_DATA]);   // copy the contents of the fields in the datagrid to the test data   // object to emulate the two-way databinding in the Windows world   foreach (DataGridItem item in dgScores.Items)   {   // get the testID for the test data in the datagrid row   testID = Convert.ToInt32(dgScores.DataKeys[item.ItemIndex]);   //get a reference to the first grade score textbox in the row   txtScore = (TextBox)(item.FindControl(FIRST_GRADE_SCORE_TEXTBOX));   // update the first grade score in the test data object   testData.set_firstGradeScore(testID,   Convert.ToInt32(txtScore.Text));   // get a reference to the second grade score textbox in the row   txtScore = (TextBox)(item.FindControl(SECOND_GRADE_SCORE_TEXTBOX));   // update the first grade score in the test data object   testData.set_secondGradeScore(testID,   Convert.ToInt32(txtScore.Text));   } // foreach   // update the test data in the database   testData.update( );   // rebind the data to the datagrid   bindData(testData);   } // if (Page.IsValid)   } // btnUpdate_Click  //************************************************************************ // // ROUTINE: btnCancel_Click // // DESCRIPTION: This routine provides the event handler for the cancel // button click event event. It is responsible for // cancel the current edits. //------------------------------------------------------------------------ private void btnCancel_Click(Object sender, System.Web.UI.ImageClickEventArgs e) { // perform the actions required to cancel the edits } // btnCancel_Click //************************************************************************ // // ROUTINE: bindData // // DESCRIPTION: This routine binds the data in the passed object to the // datagrid then persists the object in the viewstate //------------------------------------------------------------------------ private void bindData(CH06TestDataCS testData) { // bind the test data to the datagrid dgScores.DataSource = testData.testData; dgScores.DataKeyField = CH06TestDataCS.TEST_DATA_ID; dgScores.DataBind( );  // save the test data object in the view state   ViewState.Add(VS_TEST_DATA,   testData);  } // bindData } // CH06ViewStateCS } 

Example 6-17. Data service class for storage in the ViewState (.vb)
 Option Explicit On Option Strict On '----------------------------------------------------------------------------- ' ' Module Name: CH06TestDataVB.vb ' ' Description: This class provides an encapsulation of test data and ' properties/method to operate on the data. ' ' NOTE: This class is marked as serializable to provide the ability ' to serialize the objects created with the class to an ' XML string. ' '***************************************************************************** Imports Microsoft.VisualBasic Imports System Imports System.Configuration Imports System.Data Imports System.Data.OleDb  <Serializable( )> _  Public Class CH06TestDataVB  'constants used to bind the data in the encapsulated dataset   Public Const TEST_DATA_ID As String = "TestDataID"   Public Const TEST_NAME As String = "TestName"   Public Const FIRST_GRADE_PASSING_SCORE As String = "FirstGradePassingScore"   Public Const SECOND_GRADE_PASSING_SCORE As String = "SecondGradePassingScore"   Public Const MAX_SCORE As String = "MaxScore"  'constant to provide the name of the table in the dataset Private Const TEST_DATA_TABLE As String = "TestData" 'private attributes Private mTestData As DataSet Private mConnectionStr As String 'the following constant is used to query the data from the database Private Const SELECT_STR As String = "SELECT " & TEST_DATA_ID & "," & _ TEST_NAME & "," & _ FIRST_GRADE_PASSING_SCORE & "," & _ SECOND_GRADE_PASSING_SCORE & "," & _ MAX_SCORE & _ " FROM " & TEST_DATA_TABLE '************************************************************************* ' ' ROUTINE: testData ' ' DESCRIPTION: This property provides the ability to get a reference ' to the table in the dataset containing the test data. '-------------------------------------------------------------------------  Public ReadOnly Property testData( ) As DataTable   Get   Return (mTestData.Tables(TEST_DATA_TABLE))   End Get   End Property 'testData  '************************************************************************* ' ' ROUTINE: firstGradeScore ' ' DESCRIPTION: This property provides the ability to get/set the first ' grade score for the passed test ID. '-------------------------------------------------------------------------  Public Property firstGradeScore(ByVal testID As Integer) As Integer   Get   Dim dRow As DataRow   'get row with the passed testID value   dRow = mTestData.Tables(TEST_DATA_TABLE).Rows.Find(testID)   'return the first grade passing score   Return (CInt(dRow.Item(FIRST_GRADE_PASSING_SCORE)))   End Get   Set(ByVal Value As Integer)   Dim dRow As DataRow   'get row with the passed testID value   dRow = mTestData.Tables(TEST_DATA_TABLE).Rows.Find(testID)   'set the first grade passing score   dRow.Item(FIRST_GRADE_PASSING_SCORE) = Value   End Set   End Property 'firstGradeScore  '************************************************************************* ' ' ROUTINE: secondGradeScore ' ' DESCRIPTION: This property provides the ability to get/set the second ' grade score for the passed test ID. '-------------------------------------------------------------------------  Public Property secondGradeScore(ByVal testID As Integer) As Integer   Get   Dim dRow As DataRow   'get row with the passed testID value   dRow = mTestData.Tables(TEST_DATA_TABLE).Rows.Find(testID)   'return the first grade passing score   Return CInt((dRow.Item(SECOND_GRADE_PASSING_SCORE)))   End Get   Set(ByVal Value As Integer)   Dim dRow As DataRow   'get row with the passed testID value   dRow = mTestData.Tables(TEST_DATA_TABLE).Rows.Find(testID)   'set the first grade passing score   dRow.Item(SECOND_GRADE_PASSING_SCORE) = Value   End Set   End Property 'secondGradeScore  '************************************************************************* ' ' ROUTINE: update ' ' DESCRIPTION: This routine provides the ability to update the test ' data for this object in the database. '-------------------------------------------------------------------------  Public Sub update( )   Dim dbConn As OleDbConnection   Dim da As OleDbDataAdapter   Dim cmdBuilder As OleDbCommandBuilder   Try   dbConn = New OleDbConnection(mConnectionStr)   dbConn.Open( )   da = New OleDbDataAdapter(SELECT_STR, _   dbConn)   'create a command builder which will create the appropriate update,   'insert, and delete SQL statements   cmdBuilder = New OleDbCommandBuilder(da)   'update data in the testdata table   da.Update(mTestData, _   TEST_DATA_TABLE)   Finally   'cleanup   If (Not IsNothing(dbConn)) Then   dbConn.Close( )   End If   End Try   End Sub 'update  '************************************************************************* ' ' ROUTINE: New ' ' DESCRIPTION: This constructor creates the object and populates it ' with test data from the database '-------------------------------------------------------------------------  Public Sub New( )   Dim dbConn As OleDbConnection   Dim da As OleDbDataAdapter   Dim key(0) As DataColumn   Try   'get the connection string from web.config and open a connection   'to the database   mConnectionStr = _   ConfigurationSettings.AppSettings("dbConnectionString")   dbConn = New OleDbConnection(mConnectionStr)   dbConn.Open( )   'get the data from the database   da = New OleDbDataAdapter(SELECT_STR, _   dbConn)   mTestData = New DataSet   da.Fill(mTestData, _   TEST_DATA_TABLE)   'define the testID column in the data table as a primary key column   'this makes it possible to "lookup" a datarow with the testID value   'NOTE: The PrimaryKey property expects an array of DataColumn even   ' when only one column is used as the primary key   key(0) = mTestData.Tables(TEST_DATA_TABLE).Columns(TEST_DATA_ID)   mTestData.Tables(TEST_DATA_TABLE).PrimaryKey = key   Finally   'cleanup   If (Not IsNothing(dbConn)) Then   dbConn.Close( )   End If   End Try   End Sub 'New  End Class 'CH06TestDataVB 

Example 6-18. Data service class for storage in the ViewState (.cs)
 //---------------------------------------------------------------------------- // // Module Name: CH06TestDataCS // // Description: This class provides an encapsulation of test data and // properties/method to operate on the data. // // NOTE: This class is marked as serializable to provide the ability // to serialize the objects created with the class to an // XML string. // //**************************************************************************** using System; using System.Configuration; using System.Data; using System.Data.OleDb; using System.Web; namespace ASPNetCookbook.CSExamples {  [Serializable]  public class CH06TestDataCS {  // constants used to bind the data in the encapsulated dataset   public const String TEST_DATA_ID = "TestDataID";   public const String TEST_NAME = "TestName";   public const String FIRST_GRADE_PASSING_SCORE = "FirstGradePassingScore";   public const String SECOND_GRADE_PASSING_SCORE= "SecondGradePassingScore";   public const String MAX_SCORE = "MaxScore";  // constant to provide the name of the table in the dataset private const String TEST_DATA_TABLE = "TestData"; // private attributes private DataSet mTestData = null; private String mConnectionStr = null; // the following constant is used to query the data from the database private const String SELECT_STR = "SELECT " + TEST_DATA_ID + "," + TEST_NAME + "," + FIRST_GRADE_PASSING_SCORE + "," + SECOND_GRADE_PASSING_SCORE + "," + MAX_SCORE + " FROM " + TEST_DATA_TABLE; //************************************************************************ // // ROUTINE: testData // // DESCRIPTION: This property provides the ability to get a reference to // the table in the dataset containing the test data. //------------------------------------------------------------------------  public DataTable testData   {   get   {   return(mTestData.Tables[TEST_DATA_TABLE]);   }   } // testData  //************************************************************************ // // ROUTINE: set_firstGradeScore // // DESCRIPTION: This routine provides the ability to set the first grade // score for the passed test ID. //------------------------------------------------------------------------  public void set_firstGradeScore(int testID, int score)   {   DataRow dRow = null;   // get row with the passed testID value   dRow = mTestData.Tables[TEST_DATA_TABLE].Rows.Find(testID);   // set the first grade passing score   dRow[FIRST_GRADE_PASSING_SCORE] = score;   } // set_firstGradeScore  //************************************************************************ // // ROUTINE: set_secondGradeScore // // DESCRIPTION: This routine provides the ability to set the second // grade score for the passed test ID. //------------------------------------------------------------------------  public void set_secondGradeScore(int testID, int score)   {   DataRow dRow = null;   // get row with the passed testID value   dRow = mTestData.Tables[TEST_DATA_TABLE].Rows.Find(testID);   // set the second grade passing score   dRow[SECOND_GRADE_PASSING_SCORE] = score;   } // set_secondGradeScore  //************************************************************************ // // ROUTINE: update // // DESCRIPTION: This routine provides the ability to update the test // data for this object in the database. //------------------------------------------------------------------------  public void update( )   {   OleDbConnection dbConn = null;   OleDbDataAdapter da = null;   OleDbCommandBuilder cmdBuilder = null;   try   {   dbConn = new OleDbConnection(mConnectionStr);   dbConn.Open( );   da = new OleDbDataAdapter(SELECT_STR, dbConn);   // create a command builder which will create the appropriate update,   // insert, and delete SQL statements   cmdBuilder = new OleDbCommandBuilder(da);   // update data in the testdata table   da.Update(mTestData,   TEST_DATA_TABLE);   }   finally   {   // cleanup   if (dbConn != null)   {   dbConn.Close( );   }   } // finally   } // update  //************************************************************************ // // ROUTINE: CH06TestDataCS // // DESCRIPTION: This constructor creates the object and populates it // with test data from the database //------------------------------------------------------------------------  public CH06TestDataCS( )   {   OleDbConnection dbConn = null;   OleDbDataAdapter da = null;   DataColumn[] key = new DataColumn[1];   try   {   // get the connection string from web.config and open a connection   // to the database   mConnectionStr =   ConfigurationSettings.AppSettings["dbConnectionString"];   dbConn = new OleDbConnection(mConnectionStr);   dbConn.Open( );   // get the data from the database   da = new OleDbDataAdapter(SELECT_STR, dbConn);   mTestData = new DataSet( );   da.Fill(mTestData,   TEST_DATA_TABLE);   // define the testID column in the data table as a primary key column   // this makes it possible to "lookup" a datarow with the testID value   // NOTE: The PrimaryKey property expects an array of DataColumn even   // when only one column is used as the primary key   key[0] = mTestData.Tables[TEST_DATA_TABLE].Columns[TEST_DATA_ID];   mTestData.Tables[TEST_DATA_TABLE].PrimaryKey = key;   } // try   finally   {   // cleanup   if (dbConn != null)   {   dbConn.Close( );   }   } // finally   } // CH06TestDataCS  } // CH06TestDataCS } 



ASP. NET Cookbook
ASP.Net 2.0 Cookbook (Cookbooks (OReilly))
ISBN: 0596100647
EAN: 2147483647
Year: 2006
Pages: 179

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