CIS Logo SVC Logo

   Computing & Information Systems
   Department

 

Schoology Facebook        Search CIS Site      Tutorials

E-commerce App 2



The Goals for this Example


In our first e-commerce app we created an outline of an e-commerce app that sold software. The user could select a product from a drop-down list and was then given a page of information on that product. This example just adds to that application. In particular, it implements the search page that was just a placeholder before. The user can search for a software title by name or use a word or phrase to search for a desired item or items. The results are displayed in a grid view that uses paging to limit the number of rows of data seen on any page to a maximum of 4. Here is a picture of the first page of results after a search was done. As you can see, the user can click on the link labelled 2 to go to the second page of search results. Look at this screen shot of the second page of results for the same example search.

In addition, we decide not to display all of the fields about the products that match the search condition, as that would not easily fit into the grid view. Instead, each row of the grid will just display the name of the product and a button to click on to go to a new page showing all of the data on this product. In fact, we will simply redirect to the existing Results.aspx page to show all of the data on the selected product.

Starting this Project

  • Use My Computer to copy the previous project, e-commerce app 1, to a new folder in a convenient location (such as your M drive).
  • Use e2 for the name of this new project folder.
  • Open the new project in Visual Studio 2005.
  • You already have a search page named Search.aspx with very little on it.
  • We want to change this page so that it contains 2 labels, a text box, and a button as shown in this screen shot. The items in red are validators that we will add later.
  • The text for the first label is "You can search for products whose name or description contains a desired term or substring."
  • The text for the second label reads "Search for:".
  • Note that the second label's text is in bold.
  • Change the ID of the text box to SubstringBox.
  • Change the ID of the button to SearchButton and its Text field to "Search".
  • Since we included the header.txt and footer.txt files in each web form of the first e-commerce app, the Search.aspx web form should still contain this.
  • Go to HTML view and check that these 2 files are included as in the previous web app.
  • Now add a required field validator and use it to validate the text box. That is, SubstringBox should be chosen as the value of the Control to Validate field.
  • For this validator use the error message: "Cannot leave the box empty."
  • Add a regular expression validator and use it to also validate the text box.
  • Put in "Use only letters, digits, spaces -- up to 80 chars" as the error message.
  • Use [a-zA-Z0-9 ]{1,80} as the validation expression. Notice that there is a blank character after the 9. This regular expression only allows user input that consists of at least 1 and at most 80 characters, where the allowed characters are alphabetic (lower or upper case), digits, and the blank character. This would seem to be sufficient for users who want to search for our products and leaves out the more unusual characters that hackers like to use.
  • Save your work so far by using File, Save All.

The search.aspx.vb Code-Behind File

  • Adjust the Page_Load procedure so that it looks as follows:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Dim Target As String
    If IsPostBack Then   'Search button was clicked
        Page.Validate()
        If Page.IsValid Then
            Target = SubstringBox.Text.ToString()
            Session.Add("TargetSubstring", Target)
            Response.Redirect("SearchResults.aspx")
        End If
    End If
End Sub

  • The Page.Validate is present because we are using validators.
  • If a user clicks on the search button, a postback happens. In this case we use http session state to keep track of the string to search for and redirect to another page, the SearchResults.aspx form.
  • Save all of your files before going on.

Search Results



The Actual SearchResults Page

  • Add a new web form to your project and name it SearchResults.aspx.
  • Change the title of this page to "Search Results, Br. David's Software".
  • We want to set up this form as shown in this screen shot of the SearchResults page or in this view of the SearchResults form in Visual Studio.
  • Place a label at the top of this page containing the text "Search Results" in large, bold.
  • Place 4 labels for error messages just above the data list. All should use the color red. The Visible property should be False.
  • Change the ID of one label to DatabaseErrorLabel and set its Text field to "A database error happened".
  • Change the ID of another of the 4 labels to SessionErrorLabel and set its Text field to "No data was supplied".
  • Change the ID of another of the labels to NoDataLabel and set its Text field to "No matching data found".
  • Change the ID of the remaining label to ErrorLabel and set its Text field to "An error happened".
  • If security is a concern, it would be better to have only one error label with a very generic message such as "An error happened." There is no sense in giving away clues to attackers who are trying to hack your web application.
  • Drag a grid view onto this form.
  • Change the ID of the grid view to SearchResultsView.
  • Set the Visible property for SearchResultsView to False.
  • While the grid view is selected, click on the smart tag, use Autoformat, and select Colorful.
  • Use the smart tag to edit the columns of the grid view. Do the following:
    • Add a Button Field.
    • Its Header Text should be "For more info".
    • Its Text field should contain View.
    • The CommandName field should also say View.
    • See this screen shot to see what this looks like.
    • This sets up a View button that the user can click on, though we will need to have click handler code for it.
    • Also add a Bound Field.
    • Its HeaderText should be "Product name".
    • Its DataField should contain Name, the actual field name for the software title in our software table.
    • See this screen shot to see what this looks like.

The Stored Procedure

  • Create a new stored procedure as shown here:

CREATE PROCEDURE db_datareader.SelectProdSearch
(
    @Target varchar(50)
)
AS
    SET NOCOUNT ON
    SELECT DISTINCT Name FROM Software
WHERE (Name LIKE '%' + @Target + '%') OR (Description LIKE '%' + @Target + '%')
ORDER BY Name
    RETURN
  • The main idea of this stored procedure is that it selects the product name from any record of the Software table that matches the search condition.
  • What is the meaning of the search condition? By using LIKE, it checks to see if the target string occurs as a substring of the Name or Description fields.
  • Note that some databases use the * symbol instead of % as the wildcard to indicate zero or more characters.
  • In Name LIKE '%' + @Target + '%' we are specifying that the Name should be any number of characters, followed by the target string that the user is looking for, followed by any number of characters. The + is used to append the items on either side of it.
  • We also order the results of this query in ascending order by the Name field.
  • Save the stored procedure and then execute it. Give it a reasonable value for the target name and see if it returns correct results.
  • In Visual Studio do File, Save All.

Using Paging

  • Click on your grid view on the SearchResults page and under Properties set AllowPaging to True. This turns on the paging of data in the grid view.
  • Also under Properties, set the page size to 4, so as to allow up to 4 entries per page. Also set the PageButtonCount to 5, so as to allow up to 5 page buttons (links) to get to pages of results. Set the position of the page buttons to be at the bottom of the grid. The default numbered page buttons should be fine.
  • Save all of your files before proceeding further.

The SearchResults.aspx.vb Code-Behind File

  • Adjust the Page_Load procedure so that it looks as follows:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Dim Substring As String
    Dim myDatabaseConnection As SqlClient.SqlConnection = Nothing
    Dim myCommand As SqlClient.SqlCommand = Nothing
    Dim resultsDataSet As DataSet = Nothing

    If Session.Count = 0 Then   ' No session items were supplied.
        SessionErrorLabel.Visible = True
    Else
        Try
            Substring = Session("TargetSubstring")
            If Substring = "" Then
                SessionErrorLabel.Visible = True
            Else
                Dim connectionString As String = _
                ConfigurationManager.ConnectionStrings("PartsConnectionString").ConnectionString
                myDatabaseConnection = New SqlClient.SqlConnection(connectionString)
                myCommand = New SqlClient.SqlCommand()

                'Set up to use a stored procedure:
                myCommand.CommandType = CommandType.StoredProcedure
                myCommand.Connection = myDatabaseConnection
                myCommand.CommandText = "SelectProdSearch"
                myCommand.Parameters.AddWithValue("@Target", Substring)

                'Use a DataAdapter to execute the stored procedure and
                'get the results into a dataset for display in the grid view:
                Dim adapter As New SqlClient.SqlDataAdapter(myCommand)
                resultsDataSet = New DataSet
                myDatabaseConnection.Open()
                adapter.Fill(resultsDataSet)

                If resultsDataSet.Tables.Item(0).Rows.Count > 0 Then
                    ResultsGridView.DataSource = resultsDataSet
                    ResultsGridView.DataBind()
                    ResultsGridView.Visible = True
                Else
                    NoDataLabel.Visible = True
                End If
                myDatabaseConnection.Close()
                myDatabaseConnection.Dispose()
            End If
        Catch exception As System.Data.SqlClient.SqlException
            DatabaseErrorLabel.Visible = True
        Catch exception As Exception
            ErrorLabel.Visible = True
        Finally    'Do cleanup tasks here:
            myCommand = Nothing
            resultsDataSet = Nothing

            If Not myDatabaseConnection Is Nothing AndAlso _
                myDatabaseConnection.State = ConnectionState.Open Then
                myDatabaseConnection.Close()
                myDatabaseConnection.Dispose()
            End If

            myDatabaseConnection = Nothing
        End Try
    End If
End Sub
  • You should be able to follow this code by now as it is similar to what we have used before.
  • Overall, we use our data adapter and stored procedure to query the database for the Name of each product that matches our search condition. As long as we get data back, we place it in our DataSet and fill the grid with it.
  • We check resultsDataSet.Tables.Item(0).Rows.Count to see if the number of rows of data is 0. If so, then an error label is displayed. Note that resultsDataSet.Tables is a collection of the data tables in resultsDataSet. Then Item(0) is used to pick out the first (and only) data table. Rows gives the collection of rows from this data table.
  • Save all of your files before going on.
  • We need to add the following procedure to the code-behind file to handle paging in the grid view. Essentially what happens is this: With paging turned on, everytime we go to view a page of data in our grid view, we have to obtain the search results from the database (via our stored procedure). The data for the current page is displayed in the grid view, but all the other data is discarded.
  • Go ahead and make this addition:

Protected Sub ResultsGridView_PageIndexChanging(ByVal sender As Object, _
ByVal e As GridViewPageEventArgs) Handles ResultsGridView.PageIndexChanging
    Dim Substring As String
    Dim myDatabaseConnection As SqlClient.SqlConnection = Nothing
    Dim myCommand As SqlClient.SqlCommand = Nothing
    Dim resultsDataSet As DataSet = Nothing

    If Session.Count = 0 Then   ' No session items were supplied.
        SessionErrorLabel.Visible = True
    Else
        Try
            Substring = Session("TargetSubstring")
            If Substring = "" Then
                SessionErrorLabel.Visible = True
            Else
                Dim connectionString As String = _
                ConfigurationManager.ConnectionStrings("PartsConnectionString").ConnectionString
                myDatabaseConnection = New SqlClient.SqlConnection(connectionString)
                myCommand = New SqlClient.SqlCommand()

                'Set up to use a stored procedure:
                myCommand.CommandType = CommandType.StoredProcedure
                myCommand.Connection = myDatabaseConnection
                myCommand.CommandText = "SelectProdSearch"
                myCommand.Parameters.AddWithValue("@Target", Substring)

                'Use a DataAdapter to execute the stored procedure and
                'get the results into a dataset for display in the grid view:
                Dim adapter As New SqlClient.SqlDataAdapter(myCommand)
                resultsDataSet = New DataSet
                myDatabaseConnection.Open()
                adapter.Fill(resultsDataSet)

                If resultsDataSet.Tables.Item(0).Rows.Count > 0 Then
                    ResultsGridView.DataSource = resultsDataSet
                    ResultsGridView.PageIndex = e.NewPageIndex 'Change the page index!
                    ResultsGridView.DataBind()
                    ResultsGridView.Visible = True
                Else
                    NoDataLabel.Visible = True
                End If
                myDatabaseConnection.Close()
                myDatabaseConnection.Dispose()
            End If
        Catch exception As System.Data.SqlClient.SqlException
            DatabaseErrorLabel.Visible = True
        Catch exception As Exception
            ErrorLabel.Visible = True
        Finally    'Do cleanup tasks here:
            myCommand = Nothing
            resultsDataSet = Nothing

            If Not myDatabaseConnection Is Nothing AndAlso _
                myDatabaseConnection.State = ConnectionState.Open Then
                myDatabaseConnection.Close()
                myDatabaseConnection.Dispose()
            End If

            myDatabaseConnection = Nothing
        End Try
    End If
End Sub
  • The above procedure is used whenever the user clicks on the numbered buttons at the bottom of the grid view.
  • The code is almost exactly the same as that of the Page_Load procedure.
  • However, the line ResultsGridView.PageIndex = e.NewPageIndex is what is different here. This indicates what page index to use in the data grid. Because of this we see the proper page of data.
  • There is one more procedure that we need to add to this code-behind file. Add the following:

Protected Sub ResultsGridView_ItemCommand(ByVal Source As Object, _
    ByVal e As GridViewCommandEventArgs) Handles ResultsGridView.RowCommand

    If e.CommandName = "View" Then
        ' Find the index of the row where the user clicked the View button:
        Dim index As Integer = Convert.ToInt32(e.CommandArgument)
        ' Find the name of the software item in this row:
        Session.Add("ProductSelected", ResultsGridView.Rows(index).Cells(1).Text)
        Response.Redirect("Results.aspx")
    End If
End Sub
  • This procedure is called when the user does something with an item in the grid view. In our case this something is to click on one of the View buttons.
  • The code checks to see that the CommandName is View (which it will be if the user clicked on a button since we filled in "View" for the Command name for each button).
  • As long as we have a match with "View", we add to the session state that the product select is ResultsGridView.Rows(index).Cells(1).Text. As the comment says, index is the row in the grid view where the user clicked the button. The Cells(1) picks out the second cell in that row. (Remember that the counting starts at 0 and not 1.) We then use Text to get the text for that cell. This text is the product name for the product about which the user wants more information.
  • Finally, the code redirects to the existing Results.aspx form, which we used to display the details product information on a product selected from a drop-down list on the Products.aspx page. We might as well re-use this Results.aspx page instead of creating a new one that does essentially the same thing.

Testing Your Web Application

  • Save all files and build your project.
  • View your new web app locally by using Start Without Debugging and check that all pages display correctly and that the database-related code works on the products and results pages as well as on the search and search results pages.
  • On the search results page be sure to try out the navigation buttons at the bottom to see that paging works correctly. Also check the View buttons to see that they send you to the results page for detailed information on the selected product.
  • Next, publish your web app to your web server (in our case by publishing to a folder, say e2, on your W drive). Have your web server administrator mark it as an IIS web app, and then navigate to it by browser to see that all works OK.
  • You now have a very useful search capability in your web app.
Back to the main page for ASP .NET Web Apps

Author: Br. David Carlson
Last updated: November 11, 2008
Disclaimer