
Beginning ASP.NET 2.0 With CSharp (2006) [eng]
.pdf
Chapter 13
Well, you can set an attribute to track anonymous users so that even if they haven’t logged in, and have their connection to the application terminated, then when they come back they will still have their shopping cart contents intact. This is all contained within the Web.config file, which you have already partially predefined for the application in this chapter, so that your e-commerce application makes use of changes introduced to the Wrox United site in Chapter 11, and therefore requires a minimal amount of extra code. You add that capability in the next Try It Out.
Try It Out |
Amending the Profile to Use the ShoppingCart Object |
1.In the Chapter13 application, go to Solution Explorer and open the Web.config file. Scroll down to find the <profile> element and add the highlighted code:
<anonymousIdentification enabled=”true”/> <profile enabled=”true”>
<properties>
<add name=”MemberName”/> <add name=”Name”/>
<add name=”Address”/> <add name=”City”/> <add name=”County”/> <add name=”PostCode”/> <add name=”Country”/>
<add name=”Mailings” type=”System.Boolean”/> <add name=”Email”/>
<add name=”Theme”/>
<add name=”Cart” serializeAs=”Binary” type=”Wrox.Commerce.ShoppingCart” allowAnonymous=”true”/>
</properties>
</profile>
2.Save Web.config.
How It Works
Because Web.config is used by your application, the simple act of saving any changes ensures that the update is immediately applied. You’ve added only two items. The first just switches on anonymous identification, which is switched off by default:
<anonymousIdentification enabled=”true” />
The second is the cart definition:
<add name=”Cart” serializeAs=”Binary” type=”Wrox.Commerce.ShoppingCart” allowAnonymous=”true”/>
You use the type attribute to refer to the ShoppingCart object. You set the allowAnonymous attribute to true so that this particular property is tracked even when the user hasn’t logged in. Last, there is a bit of technical detail in the serializeAs property, which needn’t concern you. It simply enables you to make use of your ShoppingCart object. You can find more details about it at http://msdn2
.microsoft.com/en-us/library/system.configuration.SettingsSerializeAsAttribute
.aspx.
488

E-Commerce
The Shopping Cart Control
Unfortunately, among the multitude of new controls, there is no predefined shopping cart control that you can use, so you are going to have to create one. However, what you can do is make use of some of the existing ASP.NET 2.0 controls and you can construct a shopping cart control that you can use in any application you build. In ASP.NET 2.0, the data handling features have taken a giant leap forward, and you can use the GridView control and some clever data-binding to create your shopping cart for you.
Before you rush into building the cart, though, it’s worth thinking a little bit more about design. How are you going to access your cart? How are you going to display the items in it? The first question is easy enough to answer: You add a button to your product item page, which when clicked simply adds the item to the cart. However, where should you go then? Rather than going to your shopping cart, you probably want to return to your catalog. Shopping carts by nature should be unobtrusive — you don’t want to be confronted with the contents of your cart every time you stick an item in, which is probably not conducive to impulse buying (and by inference profitable selling). It’s much easier only to be confronted with the contents when you get to the checkout. So your system develops a structure like Figure 13-19.
Shopping Cart
Product Catalog |
Product Item |
Add an Item |
Figure 13-19
This diagram shows how you can navigate between the different parts of your application. You can move from the Product Catalog page, either to the shopping cart itself or to the Product Item page. From the Product Item page you can add an item, which in turn will appear in the shopping cart.
The second question, then, is about how you should display your shopping cart. If you were feeling extremely confident about the layout, you could probably have a little control pop up at the side that appeared in every page of the site, but because you don’t want to have to spend a lot of time with the jigsaw puzzle of fitting things into your web site design, you’ll just make the shopping cart a separate page that can be easily accessed via a separate link. You’ve already earmarked the GridView control to display the contents of your cart, so continue and build the next stage of your pipeline.
In this Try It Out, you create a user control, the ShoppingCart control, and then add it to a page. The user control is a lot more portable (you learned about them in Chapter 10 and how they help you to reuse code effectively).
Try It Out |
Adding a Shopping Cart Control |
1.Open Solution Explorer in Visual Web Developer. Right-click the top item and select Add New Item. Add a Web User Control and call it ShoppingCart.ascx.
2.In Design View, select the GridView control from the Data section of the Toolbox. Click the smart tag dialog box and select the Edit Columns option.
489

Chapter 13
3.From the dialog box that appears, select one TemplateField, four BoundFields, and one CommandField, as shown in Figure 13-20. These will be used to represent the ProductImage, ProductName, Quantity, Price, and LineTotal (that is, quantity multiplied by price) of that particular item and a button to edit that item or to delete it from your shopping cart, respectively.
Figure 13-20
4.Select the BoundFields field and change the properties one by one in the Properties window as shown in the following table.
Don’t click OK in between adding each item, which will take you back to Design View.
|
DataField |
HeaderText |
ReadOnly |
DataFormatString |
|
|
|
|
|
Bound Field 1 |
ProductName |
Product |
True |
|
Bound Field 2 |
Quantity |
Quantity |
False |
|
Bound Field 3 |
Price |
Price |
True |
{0:c} |
Bound Field 4 |
LineTotal |
Total |
True |
{0:c} |
|
|
|
|
|
5.Go to the CommandField and set the ShowEditButton and ShowDeleteButton properties to
True.
6.Click OK to go back to Design View. Click the smart tag dialog box, and select Edit Templates from the flyout that appears.
7.Now drop an Image control into the ItemTemplate and click the smart tag dialog box, as displayed in Figure 13-21.
490

E-Commerce
Figure 13-21
8.Select Edit Data Bindings and select ImageUrl from the Bindable properties. Add the following code to the Code Expression box:
Eval(“ProductImageUrl”, “~/ProductImages/thumb_{0}”)
9.Return to Design View and select the smart tag dialog box on the GridView control. Select Edit Templates EmptyDataTemplate from the menu that appears. Type the following text directly into the EmptyDataTemplate (see Figure 13-22): There is nothing in your shopping cart. You can buy items from the Shop.
Figure 13-22
10.Return to Source view and add an anchor <a> tag around the Shop section as follows:
<a href=”Wroxshop.aspx”>Shop</a>.
This is the text that will be displayed when the user views a shopping cart with no items in it. You supply a link back to the main shopping page as well.
11.In Design View, and right-click the GridView control and select Properties. Enter the values shown in the following table.
Property |
Value |
(ID) |
CartGrid |
AutoGenerateColumns |
False |
DataKeyNames |
ProductID |
12.Right-click Solution Explorer and select Add a New Item. Select a Web Form and call the new item ShoppingCartPage.aspx. Note that this is an .aspx file now unlike the user control you have just created. This is the page that will host your user control.
13.In Design View, drag ShoppingCart.ascx onto the page, as shown in Figure 13-23.
491

Chapter 13
Figure 13-23
How It Works
This finishes the first stage of your ShoppingCart control. You created your control and you added a thumbnail image and fields to store the Quantity, Price, and LineTotal of the product, as well as a button enabling you to edit or delete your choices in the cart.
If you go to Source View, it will currently look as follows:
<asp:GridView ID=”CartGrid” Runat=”server” AutoGenerateColumns=”False” DataKeyNames=”ProductID” >
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Image id=”ProductImage” Runat=”server” ImageUrl=’<%# Eval(“ProductImageURL”, “~/ProductImages/thumb_{0}”)%>’ />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField=”ProductName” HeaderText=”Product” ReadOnly=”True” />
<asp:BoundField DataField=”Quantity” HeaderText=”Quantity” /> <asp:BoundField DataField=”Price” HeaderText=”Price” DataFormatString=”{0:c}” ReadOnly=”True” />
492

E-Commerce
<asp:BoundField DataField=”LineTotal” HeaderText=”Total” DataFormatString=”{0:c}” ReadOnly=”True” /> <asp:CommandField ShowEditButton=”True” ShowDeleteButton=”true”></asp:CommandField>
</Columns>
<EmptyDataTemplate>
There is nothing in your shopping cart. You can buy items from the <a href=”wroxshop.aspx”>Shop</a>.
</EmptyDataTemplate>
</asp:GridView>
This is all very familiar and close to what you supplied to the DataList controls in your Catalog and Item pages. You bind the ProductImageURL to an image in the ItemTemplate. You have several bound fields that will display text. The price fields have settings for the DataFormatString so that they display their values correctly as prices. However, there is one setting to note. In your bound fields, you made three of the four rows read-only. The Quantity row was left editable so that you can edit the contents of your cart.
You’ve also added an EmptyDataTemplate to display a message in the event that there is nothing in the cart. However, at the moment, you have no data source. In the Catalog and Item pages, you first created a SqlDataSource control and bound it to the DataList control. You haven’t bound the ShoppingCart control to anything yet.
Automating the Shopping Cart
So far, so good, you have your ShoppingCart control fully designed. However, it doesn’t do much at the moment. In fact, it doesn’t do anything! If you want the cart to be responsive, you will need to add some code telling ASP.NET 2.0 what to do when something occurs. When you created your bound fields in the shopping cart, three of the four bound fields were read-only. The last one, Quantity, was left editable. This makes life simpler, because it means that you only need to anticipate what happens if someone changes the quantity of items within a particular row in the cart.
You will want to cater to four possible events, because there are four possible scenarios:
Editing the cart: When you enter a new quantity.
Canceling an edit in the cart: When you decide you don’t want go with the quantity value you’ve changed.
Updating the cart: When you want that new quantity to take effect.
Deleting items from the cart: When you want to completely remove an item from the cart.
This will require some code-behind. You looked at code-behind in Chapters 9 and 10. Here your codebehind will be run directly in response to one of these four events occurring. So after you’ve updated the shopping cart, how do you associate that with a particular user? You’ve already created a profile — now all you need to do is to reference that profile within your code, via the Profile object.
Go ahead and add this code to your shopping cart in the next Try It Out.
493

Chapter 13
Try It Out |
Automating the Shopping Cart |
1.Go to your ShoppingCart control. Right-click GridView and select Properties. From the Properties window, select the lightning bolt button (the fourth one), as shown in Figure 13-24. This displays a list of events.
Figure 13-24
2.Double-click the RowEditing event. In Source View, a gap appears for the events. Add the following highlighted code to the events:
protected void CartGrid_RowEditing(object sender, GridViewEditEventArgs e) { CartGrid.EditIndex = e.NewEditIndex;
BindGrid();
}
3.Go back to Design View, right-click GridView, and select Properties. It should take you straight to Events this time. Double-click the RowUpdating event. Add the following highlighted code:
protected void CartGrid_RowUpdating(object sender, GridViewUpdateEventArgs e) { TextBox QuantityTextBox = (TextBox)CartGrid.Rows[e.RowIndex].Cells[2].Controls[0];
int Quantity = Convert.ToInt32(QuantityTextBox.Text); if (Quantity == 0)
{
Profile.Cart.Items.RemoveAt(e.RowIndex);
}
else
{
Profile.Cart.Items[e.RowIndex].Quantity = Quantity;
}
CartGrid.EditIndex = -1; BindGrid();
}
4.Go back to Design View. Right-click GridView and select Properties. Double-click the RowCancelingEdit event. Add the highlighted code:
protected void CartGrid_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{ CartGrid.EditIndex = -1;
BindGrid();
}
5.In Design View, right-click GridView and select Properties. Double-click the RowDeleting event. Add the highlighted code:
protected void CartGrid_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
Profile.Cart.Items.RemoveAt(e.RowIndex);
BindGrid();
}
494

E-Commerce
6.From Design View, double-click the blank page surrounding the ShoppingCart control, and add the highlighted code to the Page_Load event:
protected void Page_Load(object sender, EventArgs e)
{
if (Profile.Cart == null) {
Profile.Cart = new Wrox.Commerce.ShoppingCart();
}
if (!Page.IsPostBack)
{
BindGrid();
}
if (Profile.Cart.Items == null)
{
TotalLabel.Visible = false;
}
}
7.You may have noticed that you’ve also referenced a function called BindGrid()within all of these events. This function does the binding so that your shopping cart can display something. You need to add this code for BindGrid() underneath the functions within the code-behind as well:
private void BindGrid()
{
CartGrid.DataSource = Profile.Cart.Items; DataBind();
TotalLabel.Text = String.Format(“Total:{0,19:C}”, Profile.Cart.Total);
}
8.At the top of the page, add a reference to your ShoppingCart object:
using Wrox.Commerce;
9.Switch to Design View and drag a Label control onto the screen and place it under the GridView control. Right-click the Label control and select Properties. Delete the Text property and change the ID property to TotalLabel, as shown in Figure 13-25.
Figure 13-25
495

Chapter 13
10.View the page ShoppingCartPage.aspx. You will see what appears in Figure 13-26.
Figure 13-26
How It Works
For the first time you’re able to browse your shopping cart, although you only get to view the EmptyDataTemplate at the moment. Your code, though, provides all of the necessary functionality to be able to use the cart properly. The RowEditing method allows you to store the ID of the Product you are editing to the index:
CartGrid.EditIndex = e.NewEditIndex;
BindGrid();
After this, you bind to the grid. The RowCancelEdit sets it back to the default of -1:
CartGrid.EditIndex = -1;
BindGrid();
This means that no row in the grid is currently selected. Once again you bind to the grid afterwards. Your Delete method removes the index number from the cart stored in the profile and binds to the grid:
Profile.Cart.Items.RemoveAt(e.RowIndex);
BindGrid();
The update first has to obtain the quantity figure from the text box, and then it converts it to an integer. If you’ve set the quantity to 0, then this acts the same as a delete, so you perform a RemoveAt to remove the CartItem object. Otherwise you simply re-adjust the quantity and reset the index to -1 and bind to the grid:
TextBox QuantityTextBox = (TextBox)CartGrid.Rows[e.RowIndex].Cells[2].Controls[0];
int Quantity = Convert.ToInt32(QuantityTextBox.Text); if (Quantity == 0)
{
Profile.Cart.Items.RemoveAt(e.RowIndex);
}
496

E-Commerce
else
{
Profile.Cart.Items[e.RowIndex].Quantity = Quantity;
}
CartGrid.EditIndex = -1; BindGrid();
You need to consider two final sections of code. The first is the BindGrid function, which performs your data binding for you and is called by each of the events:
CartGrid.DataSource = Profile.Cart.Items;
DataBind();
TotalLabel.Text = String.Format(“Total:{0,19:C}”, Profile.Cart.Total);
It simply sets the GridView control’s DataSource property to point to the Items collection of your particular profile and then sets the total for your cart.
The second second section of code to consider is the contents of the Page_Load event handler, which is fired whenever a page is started up:
if (Profile.Cart == null)
{
Profile.Cart = new Wrox.Commerce.ShoppingCart();
}
if (!Page.IsPostBack)
{
BindGrid();
}
if (Profile.Cart.Items == null)
{
TotalLabel.Visible = false;
}
This basically says, “If the cart is empty, create an empty instance of the shopping cart (so that any subsequent calls to a non-existent cart don’t fail).” It then says, “If the page hasn’t been posted back, and is therefore the first time the user has seen the page, bind the grid,” and it goes on to make the total label invisible if there is nothing in the cart and sets the format correctly for displaying the total as a currency. There is a distinction to be made here, between the first IF and third IF statement. The first IF statement will be triggered if the cart hasn’t been created. The third IF will be triggered if the cart has been created but is empty (in other words, if someone has removed all the items from it). You have to be able to handle both scenarios when updating the cart in your profile.
The Add-to-Cart Facility
Your shopping cart is now fully functional in all but one respect. You can edit it and delete items from it, but you still can’t add any items to it. This is because the adding of items needs to be done from a different page entirely.
497