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

ASP.NET 2.0 Instant Results

.pdf
Скачиваний:
67
Добавлен:
17.08.2013
Размер:
11.03 Mб
Скачать

Wrox WebShop

Figure 9-4

Design of the WebShop

To make the WebShop easy to maintain, it’s based on a three-tier architecture where the ASPX pages are separated from the business layer and data access code. The code for the business layer is located in the BusinessLogic folder in the special App_Code folder, and the data access layer can be found in the DataAccess folder. The presentation layer, consisting of .aspx and .ascx files, is located in the root of the site and in a few subfolders that are listed later.

The Business Layer

The business layer consists of five classes that are stored in the BusinessLogic folder inside the App_Code folder in the root of the web site.

Because each file in the business layer contains only one class, the file is named after the class. So you’ll find the Product class in the file Product.vb, and so on.

Product

The Product class (see Figure 9-5) represents the products that are displayed on the web site; it does not represent the actual ordered product customers can add to their shopping cart, although the two are closely related.

277

Chapter 9

Figure 9-5

The Product class itself has no defined behavior. That is, it has only properties and no methods other than a default constructor. All interaction with products, such as getting a list of products or a product instance, is carried out by the ShopManager class, which is discussed later. In addition to Id, Price, and Description properties, the Product class also has multiple PictureURL properties that are used to display images of the product in the product catalog, the detail page, and the shopping cart. The following table lists each of the eight properties of the Product class and explains their usage:

Property

Type

Description

 

 

 

CategoryId

Integer

The database of the WebShop has a Category table to

 

 

identify the various product categories. Each product is

 

 

then linked to that table through its CategoryId.

Description

String

This is the full description of the product, allowing you to

 

 

provide detailed information about it.

Id

Integer

This is the unique ID of the product in the database. The

 

 

ID is assigned by the database automatically whenever a

 

 

new product is inserted.

PictureUrlLarge

String

This property contains a virtual path to the large image of

 

 

the product. This image is used on the detail page for

 

 

each product.

PictureUrlMedium

String

This property contains a virtual path to a medium-sized

 

 

thumbnail image of the product. This image is used on

 

 

the product catalog with a list of products.

PictureUrlSmall

String

This property contains a virtual path to a small thumbnail

 

 

image of the product. This small image is used in the

 

 

shopping cart.

Price

Decimal

The price of the product.

Title

String

This is the title of the product used to identify the prod-

 

 

uct in the catalog and in the shopping cart.

 

 

 

278

Wrox WebShop

You should note that a product does not have properties like Quantity to indicate the number of items a user wants to order of a specific product. Whenever a user adds a product to the shopping cart, that product is wrapped inside an instance of the OrderedProduct class that does have these properties. The OrderedProduct class is discussed next.

OrderedProduct

In Figure 9-6, a diagram of the OrderedProduct class, you see a lot of properties that the Product class has as well. That’s no surprise, because an OrderedProduct has a lot in common with a Product. To avoid duplication of functionality and copying information from a Product to an OrderedProduct whenever an item is added to the shopping cart, the OrderedProduct class has a private member of type Product. When a new instance of an OrderedProduct is created, an instance of the Product class is passed to its constructor, which is then stored in _theProduct. Properties such as Description and PictureUrlSmall then forward their calls to the inner Product to get at the actual values.

Figure 9-6

Besides the properties that delegate their responsibility to the inner Product object, the OrderedProduct class has the following additional properties:

Property

Type

Description

 

 

 

Id

Guid

A unique ID to identify each product in the shopping cart.

 

 

This ID is generated whenever a new instance of Ordered

 

 

Product is created, and is used when existing items are

 

 

updated or removed from the cart.

ProductId

Integer

The ID of the underlying product.

Quantity

Integer

The number of items of the product that a user has ordered.

SubTotal

Decimal

Returns the read-only subtotal for the OrderedProduct

 

 

items by multiplying their quantity and the price of the

 

 

inner Product. This property is used in the shopping cart

 

 

to display the subtotal for each item.

 

 

 

279

Chapter 9

So far you have looked at classes that contain information, but cannot perform any actions. To do something useful with these classes you need some action classes that can operate on Products and OrderedProducts. Those classes are the ShoppingCart and the ShopManager, which are discussed next. Just as the Product and OrderedProduct classes, you’ll find these two classes in the BusinessLogic folder in the App_Code folder.

ShoppingCart

The ShoppingCart class (see Figure 9-7) is, as its name implies, the central storage location for OrderedProducts. An instance of the ShoppingCart class is stored in a simple session variable and made accessible through a shared property on the ShopManager class. This way, all the pages and other classes in the site can access the cart.

Figure 9-7

The ShoppingCart class contains a list with ordered products and a few methods to add, update, and remove those items. It also has properties to access the items in the shopping cart, get an item count, and get a total order amount for all the ordered products. Finally, it has a default, parameterless constructor to create new instances of type ShoppingCart.

The following table lists the properties of the ShoppingCart class:

Property

Type

Description

 

 

 

Count

Integer

Returns the total number of ordered items. It does

 

 

this by looping through the _items collection,

 

 

asking each OrderedProduct for its Quantity.

 

 

This property is read-only.

Items

List (Of OrderedProduct)

Provides read-only access to the _items list. To

 

 

add, update, or insert items in the list, the public

 

 

methods of the ShoppingCart class must be used.

 

 

This property is read-only.

Total

Decimal

Returns the total amount of money for the entire

 

 

order. It does this by looping through the _items

 

 

collection, asking each OrderedProduct for its

 

 

SubTotal. This property is read-only.

 

 

 

280

Wrox WebShop

To work with the items in the shopping cart the class exposes the following methods:

Method Name

Return

Description

 

Type

 

 

 

 

Public Sub Add

n/a

Adds a new OrderedProduct to the shopping

(ByVal theProduct

 

cart. When the item is already present, its quantity

As Product)

 

is increased instead of adding a new instance to the

 

 

cart. The product passed to this method is wrapped

 

 

inside an OrderedProduct instance that in turn is

 

 

added to the cart.

Public Sub Clear ()

n/a

Removes all items from the cart.

Public Sub Remove

n/a

Removes an item from the cart based on its unique ID.

(ByVal id As Guid)

 

 

Public Sub Update

n/a

Updates the quantity for an existing item in the cart

(ByVal newQuantity

 

based on its unique ID.

As Integer, ByVal id

 

 

As Guid)

 

 

 

 

 

These four methods are never accessed by the ASPX pages in the presentation layer directly. The presentation layer should call one of the public methods on the ShopManager class that in turn call these methods on the ShoppingCart class.

ShopManager

The ShopManager class (see Figure 9-8) is the central entity in the application that deals with Products and OrderedProducts. It is used in two parts of the application: in the front end to provide access to the shopping cart and in the back end to allow an administrator to manage the products in the product catalog.

Figure 9-8

281

Chapter 9

In addition to the ShoppingCart property, which is of type ShoppingCart, discussed earlier, the ShopManager has the following public methods:

Method Name

Return

Description

 

Type

 

 

 

 

Public Shared Sub

n/a

Adds a new OrderedProduct to the shopping

AddProductToCart

 

cart by calling the Add method of the Shopping

(ByVal theProduct

 

Cart class.

As Product)

 

 

Public Shared Sub

n/a

Deletes a product from the product catalog. This

DeleteProduct

 

method is used in the maintenance section of the

(ByVal theProduct

 

WebShop.

As Product)

 

 

Public Shared

Integer

Finalizes an order for a customer. This method

Function FinalizeOrder

 

calls the FinalizeOrder method in the data

(ByVal theCustomer

 

access layer to insert the order in the database

As Customer)

 

and then returns the new order ID.

Public Shared

Product

Returns a single instance of a product. This

Function GetProduct

 

method is used in the Product Details page to

(ByVal theProductId

 

display information about a specific product.

As Integer)

 

 

Public Shared

DataSet

Returns a DataSet with the available product

Function GetProduct

 

categories used in the catalog and the maintenance

Categories()

 

section.

Public Shared

List

Returns a list with products in the specified

Function GetProductList

(Of Product)

category. Used to display products in the product

(ByVal theCategoryId

 

catalog.

As Integer)

 

 

Public Shared Function

List

Returns a list with OrderedProducts from the

GetShoppingCartItems ()

(Of Ordered

ShoppingCart by accessing its Items property.

 

Product)

 

Public Shared Sub

n/a

Inserts a new product in the product catalog. This

InsertProduct (ByVal

 

method is used in the maintenance section of the

theProduct As Product)

 

WebShop.

Public Shared Sub

n/a

Removes an OrderedProduct from the shopping

RemoveProductFromCart

 

cart by calling the Remove method of the Shopping

(ByVal id As Guid)

 

Cart class.

Public Shared Sub

n/a

Updates an existing OrderedProduct in the

UpdateProductInCart

 

shopping cart by calling the Update method of

(ByVal newQuantity

 

the ShoppingCart class.

As Integer, ByVal id

 

 

As Guid)

 

 

 

 

 

282

Wrox WebShop

Besides these methods, the ShopManager class has a single, hidden constructor. By hiding the constructor (using the access modifier Private) you can prevent calling code from creating useless instances of the ShopManager class. Because the class exposes only shared methods and properties, there is never the need for an instance of the ShopManager.

Obviously, a shop needs customers to stay in business and the Wrox WebShop is no exception. The next section shows you what the Customer class in the WebShop looks like.

Customer

The final class in the business layer you should look at is the Customer class. The WebShop uses the Membership provider and the Profile classes to store information about the user such as login name, password, and address details. Because all of this is handled by ASP.NET automatically, why do you need an additional Customer class?

The Customer class is used to reflect the user’s details at the moment of a purchase in the WebShop. From a security standpoint it’s a good practice to disallow users to change their details, such as the shipping address, after the purchase has been finalized. This way, for example, hackers cannot change the shipping address after the order has been paid and redirect the goods to their address instead of to the customer’s.

Right before the order is finalized in the Check Out page the Customer class is filled with the user’s details, which are retrieved from the Membership and Profile providers and then passed to the FinalizeOrder method in the ShopManager class. The details from the Customer class are inserted into the database together with the other order details. So, even if a customer changes the shipping address manually, the goods will still be delivered to the address that was supplied during the ordering process. If you want to allow customers to change their order details for an order that has already been finalized, you need to implement this functionality. To make this secure, you could allow them to temporarily update their details, but postpone applying the changes to the order until they have confirmed an e-mail, for example. This way, you can be sure that the original user has requested and approved the change.

The Customer class has only seven public properties and only one method, its constructor, as shown in Figure 9-9.

Figure 9-9

283

Chapter 9

Most of the properties are pretty straightforward and don’t need an additional explanation. The only exception is the CustomerId property. This ID, implemented as a Guid, is not generated by the Customer class itself, but is retrieved from the ProviderUserKey property of the MembershipUser class. This is the unique ID for each user in the application, automatically generated and stored by the ASP.NET Framework. Because the data stored by the Membership and Profile providers is in the same database used by the rest of the WebShop application, it makes sense to reuse this unique key so it’s easy to retrieve related user details later based on this key.

All properties of the Customer class are read-only — to set their initial values, you need to pass them to the constructor of the class.

Out of the five classes in the business layer, only the ShopManager has methods that require data access to read from and write to the database. This data access is performed by the ShopManagerDB class, which is discussed in the next section.

The Data Access Layer

Two key elements make up the data access layer. First there is the database and its tables that store the data for the shop. The second part contains the methods in the ShopManagerDB class that uses stored procedures to get data in and out of the database. Because a fundamental knowledge of the database is important to understand how the data access methods work, the data model is discussed first, followed by the ShopManagerDB class.

The Data Model

For many of the operations that take place in the WebShop, a back-end database is used. This database, called WebShop.mdf and stored in the App_Data folder of the web site, stores data about products, orders, and categories. To understand how it all fits together, you should take a look at Figure 9-10, which shows the data model for the WebShop. It’s quite a simple model, with only four tables.

Figure 9-10

Figure 9-10 shows only the custom tables added for the WebShop; it does not list the tables that have been added by the Membership and Role providers. During run time, those tables are used by the ASP.NET Framework to authenticate users and determine their roles. They are not used for storing information about products, categories, or orders, other than the CustomerId in the OrderBase table that is used to determine what WebShop user placed the order. The following tables list each database table and their respective columns:

284

 

 

 

Wrox WebShop

Product

 

 

 

 

 

 

 

Column Name

Data Type

Description

 

 

 

 

 

Id

int

The Unique ID of each product. This ID is generated

 

 

 

automatically by the database each time a new product

 

 

 

is inserted.

 

Title

nvarchar(100)

The title of the product. The title is displayed on the

 

 

 

product list and details pages of the product catalog.

 

Description

nvarchar(max)

A longer description of the product. Although the

 

 

 

nvarchar(max) data type, new in SQL Server 2005,

 

 

 

allows you to store up to almost 2GB of information,

 

 

 

the description is usually limited to a few K of text,

 

 

 

describing the full product specs.

 

Price

money

The price of the product.

 

CategoryId

int

Each product is placed in a category that is displayed

 

 

 

on the web site to allow for easy navigation of the

 

 

 

product catalog. The names of the categories are stored

 

 

 

in the Category table and the Product table stores only

 

 

 

the primary key of that table as a foreign key.

 

PictureUrlSmall

nvarchar(255)

A small picture showing the product. This image is

 

 

 

shown in the shopping cart.

 

PictureUrlMedium

nvarchar(255)

A medium-sized picture showing the product. This

 

 

 

image is shown on the product list page.

 

PictureUrlLarge

nvarchar(255)

A larger picture showing the product. This image is

 

 

 

shown on the product details page.

 

Deleted

bit

Indicates whether a product is still available on the

 

 

 

web site. Because the product details are needed to

 

 

 

display information about ordered products, a product

 

 

 

can never be physically deleted from the database,

 

 

 

Instead, it’s marked as “deleted.”

Each product is linked to a category that is stored in the Category table:

Category

Column Name

Data Type

Description

 

 

 

Id

int

The unique ID of each category. This ID is generated

 

 

automatically by the database each time a new category

 

 

is inserted.

Description

nvarchar(100)

The description of the category. The description of the

 

 

category is used mainly in the navigation menu in the

 

 

main shopping area to allow a user to select a category.

285

Chapter 9

Once a customer has placed an order, the order data is stored in two tables — OrderBase and OrderDetails. The OrderBase table contains information that applies to the entire order, such as the order date and the customer that placed the order.

OrderBase

Column Name

Data Type

Description

 

 

 

Id

int

The unique ID of each order. This ID is generated

 

 

automatically by the database each time a new order

 

 

is inserted. The order ID is also communicated back

 

 

to the customer as the order number.

OrderDate

datetime

The date and time the order was placed.

CustomerId

uniqueidentifier

The ID of the customer that placed the order. This is

 

 

the primary key of the aspnet_Users table that has

 

 

been added to the database to support the Role and

 

 

Membership providers.

FirstName

nvarchar(50)

The first name of the customer.

LastName

nvarchar(50)

The last name of the customer.

Street

nvarchar(100)

The customer’s shipping address.

ZipCode

nvarchar(20)

The zip code of the customer’s address.

City

nvarchar(100)

The city of the customer’s address.

Country

nvarchar(50)

The country of the customer’s address.

 

 

 

The OrderDetail table stores information about each product a customer has ordered. This table is linked back to the OrderBase table with its OrderBaseId column.

OrderDetail

Column Name

Data Type

Description

 

 

 

Id

int

The unique ID of each order detail record. This ID is

 

 

generated automatically by the database each time a

 

 

new order detail is inserted.

OrderBaseId

int

The ID of the order to which this order detail belongs.

ProductId

int

The ID of the ordered product. This ID is used to link

 

 

back to the product table to get information such as

 

 

the title and the description.

Price

money

Because a product’s price may change after it has been

 

 

ordered, the price is stored with the order details. This

 

 

ensures that the total price for an order doesn’t change

 

 

after it has been confirmed by a customer.

Quantity

int

The number of items of the product the customer has

 

 

ordered.

 

 

 

286