Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Beginning ASP.NET 2.0 With CSharp (2006) [eng]

.pdf
Скачиваний:
83
Добавлен:
16.08.2013
Размер:
20.33 Mб
Скачать

Chapter 13

might require from a site might be unduly influenced by you looking at other vendors’ sites. So you’re going to have a quick think now. It doesn’t matter if you don’t get it absolutely right the first time, because you can amend it as you go along.

With your shopping cart, a good first stab would be the following list of attributes:

A representation of the item

The quantity of the item

The price of the item

The total price

For the representation of the item, you could quite easily use the title or the description of the item, but given that you have some thumbnail pictures at hand, it would be nice to use them as well. In your cart you will start with the name and a link to the image of the item purchased. The quantity and the price are both self-explanatory enough. However, the total price needs a little expanding. You could have a total price as shown in the following table.

Item

Quantity

Price

Scarf

2

$4.95

Bug

2

$0.75

Total Price

 

$11.40

It looks a little strange. That’s because you’re immediately totalling the $4.95 and the 75 cents, and they don’t add up to make $11.40. So as well as the total price, it might be better to do it spreadsheet style and total the price and the quantity first and create a total for each line, as shown in the following table.

Item

Quantity

Price

Item Total

 

 

 

 

Scarf

2

$4.95

$9.90

Bug

2

$0.75

$1.50

Total Price

 

 

$11.40

Now add line total to the list of attributes you want to store. That’s as much as you need for each

CartItem, so let’s move onto the ShoppingCart.

The ShoppingCart Object

The CartItem object was the easiest, because it’s fairly static in its conception. Either you have a CartItem object or you don’t, unless you prescribe to some sort of parallel universe theory where you can have both at the same time. However, computing is quite complicated enough already without parallel universes to think about, too. The reason the ShoppingCart object is more complex is because it will comprise one or several items in the cart. So you immediately need somewhere to store a stack of cart items in your object. Rather than a warehouse or a shopping trolley, you can use the collections talked about in Chapter 9 to do this.

478

E-Commerce

This also raises other questions, namely how do you differentiate between different items in the cart, and how do you maintain some sort of order with them? The answer is to add an index, so that, for example, if you add a scarf and that is item 1 in the cart, and then you add a bug, that becomes item 2 in the cart.

Your cart will also need to deal with the set of possible actions that you can perform on the contents of the cart. Briefly the most common actions you might perform on a shopping cart are as follows:

Adding an item to the cart

Updating the information about an item in the cart

Updating the total price of all of the items in the cart

Deleting an item from the cart

You will need to handle these four actions. Last, because you are keeping a record of all of the items within the cart, it might be easier to move the total purchase price across to this object instead. This is just the kind of amendment we talked about earlier when creating a design. Better to discover it now, than when you’ve actually created it. So the things you are going to have built into your ShoppingCart object are the cart item collection; an index; the add, update, and delete actions; and a final total.

Now that you’ve got an outline of what you need to store, in this Try It Out you build the object to store it.

Try It Out

Building the ShoppingCart Object

1.Go to Solution Explorer, right-click the top item, and select Add New Item. Choose Class and call it Shopping.cs.

2.Click Add. Visual Web Developer might inform you that you are attempting to add a class to an ASP.NET application and that it should be moved to the App_Code folder to be generally consumable. If so, then click Yes to accept this proposition.

3.Add the following code to create a shopping cart item object, called CartItem:

using System.Data; using System.Web;

using System.Data.SqlClient; using System.Collections.Generic;

namespace Wrox.Commerce

{

[Serializable] public class CartItem

{

private int _productID; private string _productName;

private string _productImageUrl; private int _quantity;

private double _price; private double _lineTotal;

public void New()

479

Chapter 13

{

}

public void New(int ProductID , string ProductName , string ProductImageUrl , int Quantity ,

double Price )

{

_productID = ProductID; _productName = ProductName; _productImageUrl = ProductImageUrl; _quantity = Quantity;

_price = Price;

_lineTotal = Quantity * Price;

}

public int ProductID

{

get

{

return _productID;

}

set

{

_productID = value;

}

}

public string ProductName

{

get

{

return _productName;

}

set { _productName = value;

}

}

public string ProductImageUrl

{

get

{

return _productImageUrl;

}

set

{

_productImageUrl = value;

}

}

public int Quantity

{

get

{

480

E-Commerce

return _quantity;

}

set

{

_quantity = value;

}

}

public double Price

{

get

{

return _price;

}

set

{

_price = value

}

}

public double LineTotal

{

get

{

return _quantity * _price;

}

}

}

}

4.Underneath the CartItem class, add the following code to create the ShoppingCart object:

[Serializable]

public class ShoppingCart

{

private DateTime _dateCreated; private DateTime _lastUpdate; private List<CartItem> _items;

public ShoppingCart()

{

if (this._items == null)

{

this._items = new List<CartItem>(); this._dateCreated = DateTime.Now;

}

}

public List<CartItem> Items

{

get

{

return _items;

481

Chapter 13

}

 

set

 

{

 

_items = value;

 

}

 

}

 

public void Insert (int ProductID , double Price,

 

int Quantity, string ProductName ,

 

string ProductImageUrl )

 

{

 

int ItemIndex = ItemIndexOfID(ProductID);

 

if (ItemIndex == -1)

 

{

 

CartItem

 

NewItem = new CartItem();

 

NewItem.ProductID = ProductID;

 

NewItem.Quantity = Quantity;

 

NewItem.Price = Price;

 

NewItem.ProductName = ProductName;

 

NewItem.ProductImageUrl = ProductImageUrl;

 

_items.Add(NewItem);

 

}

 

else

 

{

 

_items[ItemIndex].Quantity += 1;

 

}

 

_lastUpdate = DateTime.Now;

 

}

 

public void Update(int RowID, int ProductID,

int Quantity

, double Price )

 

{

 

CartItem Item = _items[RowID];

 

Item.ProductID = ProductID;

 

Item.Quantity = Quantity;

 

Item.Price = Price;

 

_lastUpdate = DateTime.Now;

 

}

 

public void DeleteItem(int rowID )

 

{

 

_items.RemoveAt(rowID);

 

_lastUpdate = DateTime.Now;

 

}

 

private int ItemIndexOfID(int ProductID )

 

{

 

int index=0;

 

foreach (CartItem item in _items)

 

{

 

if (item.ProductID == ProductID)

 

{

 

return index;

 

 

 

482

E-Commerce

}

index += 1;

}

return -1;

}

public double Total

{

get

{

double t=0;

if (_items == null)

{

return 0;

}

foreach (CartItem Item in _items)

{

t += Item.LineTotal;

}

return t;

}

}

}

}

5.Save this page. Unfortunately you can’t do anything with the class until you come to instantiate an instance of the object, so there’s nothing to see just yet.

How It Works

The ShoppingCart class provides you with an object that you can just insert into your code. You start by defining both objects as being in the Wrox.Commerce namespace. This means that you can insert them into any page by using the following reference at the top of a page:

<%@ Import Namespace = “Wrox.Commerce” %>

This reference enables you to make use of all of the properties and methods within the ShoppingCart object. There is a lot of code here within the object, so let’s briefly skip through what is happening with each object inside the ShoppingCart object.

The CartItem is just a series of properties to store each of the cart attributes in. You define a set of private variables that represent each of the items in your CartItem object. In addition to the five previously mentioned, the productID is there so you can uniquely identify the type of item:

private int _productID; private string _productName;

private string _productImageUrl; private int _quantity;

private double _price; private double _lineTotal;

483

Chapter 13

The productID attribute is an integer, because it stores your unique identifier. The productName attribute is text, so you store that as a string. Next comes the productImageUrl attribute. Rather than store a physical image, you store a URL of the location where you can find that image (thus saving you from having to physically store the images in the database), which is also stored as text. The quantity attribute is stored as an int, because it is impossible to have a fraction of an item (Wrox United doesn’t sell half a scarf, or a bug with two legs). The price attribute, however, is a representation of currency, so that requires a double data type because you will be dealing with fractions. The lineTotal attribute is made from quantity multiplied by price, so that must also be a double data type.

Each of these attributes must be both readable and writable, so you create a set of properties for each in this format, using the ProductID() property as an example:

public int ProductID

{

get

{

return _productID;

}

set

{

_productID = value;

}

}

Each of the properties takes this format with both Get and Set constructors, referencing the variables you defined at the top of the ShoppingCart definition. The only one that is any different is the LineTotal() property, which is a multiplication of the quantity and price properties. You don’t want anyone to be able to alter this because you change it yourself, so it only has a get constructor:

public double LineTotal

{

get

{

return _quantity * _price;

}

}

That sums up the entire CartItem object. The ShoppingCart object is a little trickier. Because you are constantly updating your shopping cart, you need to keep a track of when it was created and when it was last updated. You start by defining a couple of variables that do this for you:

private DateTime _dateCreated; private DateTime _lastUpdate;

These two variables store the time at which the ShoppingCart object was created and the time at which it was last updated. Next you create the collection. The collection is a List object and it contains a list of CartItem objects. The ShoppingCart constructor that you can call in your code is used to create a new instance of a shopping cart:

public ShoppingCart()

{

if (this._items == null)

484

E-Commerce

{

this._items = new List<CartItem>(); this._dateCreated = DateTime.Now;

}

}

You create a property called Items in which to store your List of CartItems:

public List<CartItem> Items

{

get

{

return _items;

}

set

{

_items = value;

}

}

Then you come to your four actions, which you code as three methods (the two update actions are handled in one Update action). The first method insert requires all the information that your cart requires, namely ProductID, Quantity, Price, ProductName, and the ProductImageUrl:

public void Insert (int ProductID , double Price,

int Quantity, string ProductName , string ProductImageUrl )

{

int ItemIndex = ItemIndexOfID(ProductID); if (ItemIndex == -1)

{

CartItem

NewItem = new CartItem(); NewItem.ProductID = ProductID; NewItem.Quantity = Quantity; NewItem.Price = Price; NewItem.ProductName = ProductName;

NewItem.ProductImageUrl = ProductImageUrl; _items.Add(NewItem);

}

else

{

_items[ItemIndex].Quantity += 1;

}

_lastUpdate = DateTime.Now;

}

When you add a new item into the cart (the Insert method), you need to create an index to track this. If the index is –1, you know that item is not already present in the cart, and you need to create a new cart item with the accompanying ProductID, Quantity, Price, ProductName, and ProductImageUrl details. If it is present, you just need to add one to the quantity. Because you have just made the last update to the cart, you also need to record this in the lastUpdate variable and use the DateTime.Now function to record the current date and time.

485

Chapter 13

The Update action is in fact just a recalculation of Price; as mentioned earlier. Quantity is the only item you can actually change when you update the cart details. (If you think about it, this makes sense, because you can’t have the customers updating the price, product name, or description.) The quantity affects the price.

public void Update(int RowID, int ProductID,

int Quantity ,

double Price )

 

{

 

CartItem Item = _items[RowID];

 

Item.ProductID = ProductID;

 

Item.Quantity = Quantity;

 

Item.Price = Price;

 

_lastUpdate = DateTime.Now;

 

}

 

You identify the item again using the index. You read the ProductID, the Quantity, and the Price from the CartItem collection, and set it to the new Quantity for your chosen product. You update the time the cart was updated as well.

You’ve looked at the Update and Insert methods, so that just leaves the question of how customers can remove items from the cart. This is done via the Delete method. The Delete method is the simplest of the three — all you need to do is use the index to identify which item has been selected for deletion and remove it with the RemoveAt method. You also set the _lastUpdate variable to contain the current time, because you have just updated the cart by deleting an item from it:

public void DeleteItem(int rowID )

{

_items.RemoveAt(rowID); _lastUpdate = DateTime.Now;

}

Under the Insert, Update, and DeleteItem methods is the index property. The index property is as follows:

private int ItemIndexOfID(int ProductID )

{

int index=0;

foreach (CartItem item in _items)

{

if (item.ProductID == ProductID)

{

return index;

}

index += 1;

}

return -1;

}

The index, which is used to identify each item in the cart, stores each product’s Product ID. If the first item in the cart was a scarf, then the first item in the index will contain the scarf’s ProductID. If you haven’t got a ProductID, you return -1 instead to indicate that this product is not currently in the cart, and that you need to create a CartItem object for it.

486

E-Commerce

The Total comes last:

public double Total

{

get

{

double t=0;

if (_items == null)

{

return 0;

}

foreach (CartItem Item in _items)

{

t += Item.LineTotal;

}

return t;

}

}

}

It’s a fairly simple property too. If there are no items in your collection (you check this by seeing if it Is Nothing) then you don’t have any arithmetic to do. Otherwise, you iterate through each Item in the CartItem collection, adding the LineTotal property for that item, and you return the total amount as the variable t.

The Profile

You have your ShoppingCart object, which will act as the memory of the shopping cart, but this still doesn’t answer a key question — how are you going to keep this shopping cart if your user gets his Internet connection violently terminated? In fact, you’ve already looked at the solution to this in a previous chapter.

In Chapter 11, you looked at how you can create a user profile and how it can be used to create a particular personalized view of the site for any user who logs on to the site. In particular, you stored the member’s name, address (including city, county, and country), e-mail, whether he wanted to receive mailings or not, and his particular theme of the site. It is via this capability that you can also store the ShoppingCart object. Rather than getting you to create the whole profile, we’ve already provided it in the ready-to-go application that is available for download from www.wrox.com for this chapter.

I can hear the wiseguys at the back now — so I see how to save the cart, but surely you still have to log in to get associated with your cart? That’s where the wiseguys are wrong. Another great new feature of ASP.NET is the capability to track seemingly anonymous users via the personalization and profiling system. If the wiseguys had been paying attention in Chapter 11, they would have known that.

In Chapter 11, you saw how you could set up a template to handle anonymous users, and how you could also migrate the details from the anonymous person’s shopping cart to the bona fide logged-in user’s shopping cart. Now it’s time to fill in the other jigsaw pieces. How does this fit into the overall shopping cart picture?

487