Ecommerce App: Software 2
The Goals for this Example
This example adds to the software 1 simple ecommerce app for selling software online via download.
The main addition is a working search page that allows the user to look up software products that contain a certain target
string within either the name of the software item or its description. Paging of the results of the search is also done,
as the results might not fit what one can see all at once in a reasonably-sized grid view.
Getting Started
Preliminaries
- These images show some screen shots of the running app:
- You can best see what we are aiming for by trying the
actual software2 web app.
- Begin by making a copy of your software1 website folder. Name it software2.
- Also, use Add, Add New Item, Web Form to add to your web site an ordinary web forms named SearchResults.aspx.
Be sure to check the box that says "Select master page". After you click on the Add button,
you will then be able to select the master page that we used for the software1 web app.
- Let's make a small improvement to the Results.aspx page. Unless you fixed this when writing the software1 app,
your Results page probably displays a small broken image for products that have no URL for an image. Fix this in
Results.aspx.vb by adding an IF test to check if the ImageURL of the selected product is Nothing. If it is Nothing
set the Visible property to False for the product image. Otherwise, copy the ImageURL into the ImageUrl field of
the product image and make this image visible.
|
Modifications to the Search.aspx Page
- The Search.aspx page copied from the software1 project had little on it.
In source view, make sure that the title is set to "Search, Br. David's Software" or similar.
Also enable Session state by adding EnableSessionState="True" to the directive on the first line.
- Then make the Search.aspx form look like that seen in this image.
- Note that the first item is a label displaying the text
"You can search for products whose name or description contains a desired term or substring."
- Then there is a label that says "Search for:"
- To the right of that is a text box with ID SubstringTextBox.
- Below these, there is a button that says Search. Use SearchButton for its ID.
- At the bottom of the ContentPlaceholder are two validators. One is a required field validator for the text box.
Unlike labels used for error messages, validators should have their Visible property set to True.
For the required field validator, set the text to "Cannot leave the box empty."
Make sure it validates the text box (by using the ControlToValidate property).
- The other validator is a regular expression validator. It's text should be
"Use only letters, digits, spaces -- up to 64 chars."
In the ValidationExpression property, type in the regular expression [a-zA-Z0-9 ]{1,64}, as that is perfect
for insisting on letters, digits, or spaces and on having 1 to 64 such characters. Of course, the ControlToValidate
should be the text box. These validators will keep users from accidentally or maliciously submitting garbage via
the text box.
- Because of using validators, you should turn off unobtrusive validation, as in
previous examples.
|
The Search.aspx.vb Code-Behind File
- The box below has an outline of the code needed for your Page_Load event handler.
- If you do not already have the beginning of this event handler in Search.aspx.vb, you can create the shell of one
by double clicking on the bottom of your Search.aspx form (in the region for the master page).
- All this code does is to check the validators, and if all is OK to put the search string into Session state
and redirect to the new page, SearchResults.aspx, which we will work on next.
|
If IsPostBack Then ' Search button was clicked
Page.Validate()
If Page.IsValid Then
' Add the text from the text box to Session state under some reasonable name.
' Redirect to the SearchResults.aspx page (yet to be created)
End If
End If
|
The SearchResults.aspx Page
- Change the title of this page to "Search Results, Br. David's Software".
- In the directive on the first line, while in Source view, place EnableSessionState="True", as we will need to
use Session state.
- We want to set up this form as shown in this view of the SearchResults form
in Visual Studio.
- Notice that we do not try to display all of the info about the matching software products on this page. Instead, we just
show the name of each matching product and provide a View button to click on to see the details on that product.
- Place a label at the top of this page containing the text "Search Results" in large, bold.
- Place 4 labels for error messages to the right of that first label.
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 NoMatchLabel and set its Text field to
"No matching data was 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. On the other hand, while we are developing our app, more detailed
error messages are helpful to us.
- Drag a grid view onto this form.
- Change the ID of the grid view to SearchResultsGridView.
- Set the Visible property for SearchResultsGridView to False.
- While the grid view is selected, click on the smart tag, use Autoformat, and select Classic.
- Use the smart tag to edit the columns of the grid view. Do the following:
- Add a Button Field.
- Set ButtonType to Button.
- Its Header Text should be "For more info".
- Its Text field should be View.
- The CommandName field should also be View.
- See this image of the fields window 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 before it will do anything.
- Click on your grid view. Under Properties set AllowPaging to True.
This turns on the paging of data in the grid view.
- Similarly, set PageSize to 5, so as to allow up to 5 entries per page.
- Also set the PageButtonCount to 3, so as to allow up to 3 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.
|
The Code for SearchResults.aspx.vb
- Create the beginning of a Page_Load event handler for SearchResults in the usual way.
- This code should use the Entity Framework and LINQ to get the names of the software products matching the string that
the user provided on the Search page and that is now stored in Session state.
- These names and associated View buttons should be shown in the grid view.
- Follow the outline below for the code for this Page_Load routine.
- Notice that we look for a loose match for the user-supplied string. We use Contains to see if it is a substring
of either the name or description of each software product.
- Follow http://codesamplez.com/database/linq-to-sql-like-operator for more information on using the Contains function as well as the similar StartsWith and EndsWith functions.
- The OrElse is the VB short-circuit evaluation for Or. That is, if the condition on the left is True, it does not
even check the condition on the right.
|
Dim Substring As String
If Session.Count = 0 Then ' No session items were supplied.
' Make the SessionErrorLabel visible.
Else
Try
Substring = ' Retrieve from Session state the user's string that was saved there.
If Substring = "" Then
' Make the SessionErrorLabel visible.
Else
' Place the typical Using statement here for our Entities.
' You will then need a statement such as the following, though your names may differ.
Dim Products = From Software In softEntities.Softwares Order By Software.Name
Where Software.Name.Contains(Substring) OrElse Software.Description.Contains(Substring)
Select Software.Name
' If the count of Products is greater than 0 Then
SearchResultsGridView.DataSource = Products.ToList()
SearchResultsGridView.DataBind()
SearchResultsGridView.Visible = True
Else
NoMatchLabel.Visible = True
End If
End Using
End If
Catch exception As System.Data.SqlClient.SqlException
DatabaseErrorLabel.Visible = True
Catch exception As Exception
ErrorLabel.Visible = True
End Try
End If
|
- Next, click on the grid view. Find the lightning bolt button in properties and click on it to see all of the
possible events for the grid view. Doulble click on PageIndexChanging to get the shell of an event handler for this.
- The code for this click handler is the same as that for the Page_Load event handler above, except that one new line
has been added. That extra line tells the grid view what page we want to see, which is the page whose index is retrieved
from parameter e.
- Here is an outline of the code:
|
Protected Sub SearchResultsGridView_PageIndexChanging(sender As Object, e As GridViewPageEventArgs)
Handles SearchResultsGridView.PageIndexChanging
Dim Substring As String
If Session.Count = 0 Then ' No session items were supplied.
' Make the SessionErrorLabel visible.
Else
Try
Substring = ' Retrieve from Session state the user's string that was saved there.
If Substring = "" Then
' Make the SessionErrorLabel visible.
Else
' Place the typical Using statement here for our Entities.
' You will then need a statement such as the following, though your names may differ.
Dim Products = From Software In softEntities.Softwares Order By Software.Name
Where Software.Name.Contains(Substring) OrElse Software.Description.Contains(Substring)
Select Software.Name
' If the count of Products is greater than 0 Then
SearchResultsGridView.DataSource = Products.ToList()
SearchResultsGridView.PageIndex = e.NewPageIndex ' The one new line of code!
SearchResultsGridView.DataBind()
SearchResultsGridView.Visible = True
Else
NoMatchLabel.Visible = True
End If
End Using
End If
Catch exception As System.Data.SqlClient.SqlException
DatabaseErrorLabel.Visible = True
Catch exception As Exception
ErrorLabel.Visible = True
End Try
End If
End Sub
|
- Once again, click on the grid view to make sure it is selected. Then find the lightning bolt button in Properties
and click on it to see the list of possible events. Doulble click on RowCommand to get the shell of an event handler.
This one handles the situtation when the user clicks on the View button for a particular row.
- Use the following outline as a guide.
- Note that Cells(0) is the first column in the grid view, Cells(1) is the second column, etc. Since the View button
is in the first column, Cells(1) picks up the name of the software product from the second column.
|
Protected Sub SearchResultsGridView_RowCommand(sender As Object, e As GridViewCommandEventArgs)
Handles SearchResultsGridView.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 like this:
' Add SearchResultsGridView.Rows(index).Cells(1).Text to Session state under the
' name needed by the Results.aspx page.
' Then redirect to the Results.aspx page.
End If
End Sub
|
|