The shopping cart for the store appears within the Default.aspx , Category.aspx , and Product.aspx pages. For example, Figure 31.2 displays what the shopping cart looks like in the Products page. Figure 31.2. The shopping cart.
The shopping cart actually has two parts . The user interface portion of the shopping cart is implemented as a user control. The source code for the ShoppingCart.ascx user control is contained in Listing 31.4. Listing 31.4 ShoppingCart.ascx<%@ Import Namespace="StoreComponents" %> <Script runat="Server"> Dim intProductID As Integer Dim intCategory As Integer Dim strProductName As String Dim decUnitPrice As Decimal Dim objShoppingCart As ShoppingCart Sub Page_Load intProductID = Context.Items( "ProductID" ) intCategory = Context.Items( "Category" ) strProductName = Context.Items( "ProductName" ) decUnitPrice = Context.Items( "UnitPrice" ) objShoppingCart = New ShoppingCart If Not IsPostBack Then If intProductID = -1 Then btnAdd.Visible = False End If BindDataGrid End If End Sub Sub Page_PreRender If objShoppingCart.Items.Count = 0 Then btnCheckOut.Visible = False Else btnCheckOut.Visible = True btnCheckOut.NavigateUrl = String.Format( _ "/aspnetstore/CheckOut.aspx?cat={0}", intCategory ) End If End Sub Sub btnAdd_Click( s As Object, e As EventArgs ) objShoppingCart.Add( intProductID, strProductName, decUnitPrice ) BindDataGrid End Sub Sub LinkButton_Click( s As Object, e As DataGridCommandEventArgs ) objShoppingCart.Remove( e.Item.ItemIndex ) BindDataGrid End Sub Sub BindDataGrid dgrdShoppingCart.DataSource = objShoppingCart.Items dgrdShoppingCart.DataBind() End Sub </Script> <table> <tr> <td> <font face="Arial" size="3"> Your Shopping Cart </font> </td> </tr> <tr> <td> <asp:DataGrid id="dgrdShoppingCart" OnItemCommand="LinkButton_Click" AutoGenerateColumns="False" GridLines="Horizontal" BackColor="White" BorderStyle="Solid" BorderColor="Black" BorderWidth="2" Width="200" CellPadding="4" Font-Face="Arial" Font-Size="10pt" HeaderStyle-Font-Face="Arial" HeaderStyle-Font-Size="10pt" HeaderStyle-BackColor="orange" Runat="Server"> <Columns> <asp:TemplateColumn> <ItemTemplate> <asp:LinkButton Text="x" Style="color:red;font:bold 12pt Arial;text-decoration:none" Runat="Server" /> </ItemTemplate> </asp:TemplateColumn> <asp:BoundColumn DataField="ProductName" HeaderText="item" /> <asp:BoundColumn DataField="UnitPrice" DataFormatString="{0:c}" HeaderText="price" /> <asp:BoundColumn DataField="Quantity" HeaderText="qty" /> </Columns> </asp:DataGrid> </td> </tr> <tr> <td align="right"> Total: <%=String.Format( "{0:c}", objShoppingCart.GetItemTotal() )%> </td> </tr> <tr> <td align="right"> <asp:LinkButton id="btnAdd" Text="Add to Cart" OnClick="btnAdd_Click" Runat="Server" /> <asp:HyperLink id="btnCheckOut" Text="Check Out" Runat="Server" /> </td> </tr> </table> The C# version of this code can be found on the CD-ROM. Listing 31.4 is long, but easy to understand. The majority of Listing 31.4 is devoted to formatting a DataGrid control to look like a tiny shopping cart. Two links appear directly below the shopping cart. One link enables you to add the current product to your shopping cart. The second link enables you to purchase all the items in your shopping cart by going to the CheckOut.aspx page. When you click the Add to Cart link, the btnAdd_Click subroutine executes. This subroutine adds a new item to the shopping cart by calling the Add method of the ShoppingCart class. All the database functionality for the shopping cart control is implemented within the StoreComponent assembly in a class named, appropriately enough, ShoppingCart . The full source for this class is contained in Listing 31.5. Listing 31.5 ShoppingCart.vb [View full width] Public Class ShoppingCart Private _conCart As SqlConnection Private _dadCart As SqlDataAdapter Private _dstCart As DataSet Private _cbCart As SqlCommandBuilder Private _guidUserID As GUID Sub New() Dim strConString As String Dim strSelect As String Dim objCookie As HttpCookie ' Prepare db connection strConString = ConfigurationSettings.AppSettings( "connectionString" ) _conCart = New SqlConnection( strConString ) ' Check for StoreUserID cookies objCookie = HttpContext.Current.Request.Cookies( "StoreUserID" ) If objCookie Is Nothing Then _guidUserID = Guid.NewGuid objCookie = New HttpCookie( "StoreUserID", _guidUserID.ToString ) objCookie.Expires = DateTime.Now.AddYears( 3 ) HttpContext.Current.Response.Cookies.Add( objCookie ) Else _guidUserID = New GUID( objCookie.Value ) End If ' Retrieve the shopping cart strSelect = "Select itemID, userID, ProductID, ProductName, UnitPrice, Quantity From ShoppingCarts Where userID = @userID" _dadCart = New SqlDataAdapter( strSelect, _conCart ) _dadCart.SelectCommand.Parameters.Add( "@userID", _guidUserID ) _dadCart.MissingSchemaAction = MissingSchemaAction.AddWithKey _cbCart = New SqlCommandBuilder( _dadCart ) _dstCart = New DataSet _dadCart.Fill( _dstCart, "Cart" ) End Sub Public ReadOnly Property Items As DataView Get Return _dstCart.Tables( "Cart" ).DefaultView End Get End Property Public Sub Add( ProductID As Integer, ProductName As String, UnitPrice As Decimal ) Dim blnMatch As Boolean = False Dim drowItem As DataRow For each drowItem in _dstCart.Tables( "Cart" ).Rows If drowItem( "ProductID" ) = ProductID Then drowItem( "Quantity" ) += 1 blnMatch = True Exit For End If Next If Not blnMatch Then drowItem = _dstCart.Tables( "Cart" ).NewRow drowItem( "UserID" ) = _guidUserID drowItem( "ProductID" ) = ProductID drowItem( "ProductName" ) = ProductName drowItem( "UnitPrice" ) = UnitPrice drowItem( "Quantity" ) = 1 _dstCart.Tables( "Cart" ).Rows.Add( drowItem ) End If UpdateCartDB End Sub Public Sub Remove( ItemIndex As Integer ) _dstCart.Tables( "Cart" ).Rows( itemIndex ).Delete UpdateCartDB End Sub Function GetItemTotal() As Decimal Dim intCounter As Integer Dim drowItem As DataRow Dim decRunningTotal As Decimal For intCounter = 0 To _dstCart.Tables( "Cart" ).Rows.Count - 1 drowItem = _dstCart.Tables( "Cart" ).Rows( intCounter ) decRunningTotal += ( drowItem( "UnitPrice" ) * drowItem( "Quantity" ) ) Next Return decRunningTotal End Function Private Sub UpdateCartDB _dadCart.Update( _dstCart, "Cart" ) End Sub End Class The C# version of this code can be found on the CD-ROM. The shopping cart contained in Listing 31.5 automatically tracks users through a cookie named StoreUserID . The shopping cart automatically creates a persistent cookie that lasts (in theory at least) three years . When a user returns to the store, all the items that the user previously added to the shopping cart will still be there. The nice thing about this feature is that it works even if the user never registers at the Web site. If an anonymous user adds items to a shopping cart and waits several months to return to the site, all the items previously selected will remain in the shopping cart. The cookie is created with a Globally Unique Identifier (GUID). The NewGuid method of the Guid structure can return a GUID in a number of different formats. In this case, you just use the default string version of the GUID. Behind the scenes, the shopping cart in Listing 31.5 is implemented as a DataSet . A DataAdapter is used to create the DataSet and to update the existing database table when changes are made to the data. In the constructor subroutine in Listing 31.5, a DataAdapter is used to retrieve the shopping cart from the ShoppingCarts table. If any kind of change is made to a shopping cart item, the UpdateCartDB subroutine is called. The UpdateCartDB subroutine contains only the following statement: dadCart.Update( _dstCart, "Cart" ) This statement saves any changes to the shopping cart to the ShoppingCarts table. The DataAdapter Update statement automatically checks each row in DataTable for changes between its original and current value. If a change is discovered , the Update() method executes a SQL command to modify the data in the database to match the new value of the row. |