E-Commerce 2

Download Report

Transcript E-Commerce 2

CHAPTER3
Creating the Product Catalog: Part I
E-Commerce
Hassanin M. Al-Barhamtoshy
[email protected]
How This Chapter Is Structured
The main topics we’ll touch on in this chapter are:
1. Analyzing the structure of the product catalog and
the functionality it should support
2. Creating the database structures for the catalog
and the data tier of the catalog
3. Implementing the business tier objects required
to make the catalog run, and putting a basic but
functional error-handling strategy in place
4. Implementing a functional UI for the product
catalog
What Does a Product Catalog Look Like?
 The store has a number of departments.
 Each department will contain a number of
categories.
 Each category can then have any number
of products attached to it.
Graphical User Interface Designing
 Accessibility:
 Standard GUI
 Blind Users (Color Blind)
 Movement Difficulties
 Sign Language Interface
 Braille (Active Content – no Images)
 Localization and Globalization
 Multi Languages
 Navigation
Installing the Software
 Visual Web Developer 2005
 http://lab.msdn.microsoft.com/expre
ss/
 SQL Server 2005
 SQL Server Express Manager
 Check to install SQL Server 2005 Express Edition.
 IIS 5.x

Go to the Control Panel and select the Add or Remove
Programs icon.
Previewing the Product Catalog
•In the figure, you can see the BalloonShop front page and four of its
featured products.
Previewing the Product Catalog
In the figure, you see the page that will appear when the “Anniversary
Previewing the Product Catalog
In the figure, you can see how that page appears when selecting the
“Birthdays” category. Also note the paging controls, which appear in
any product listings that contain more than an established number
of products.
Previewing the Product Catalog
•
In any page that displays products, you can click the name or the picture of a
product to view its product details page (see the figure). In later chapters, you’ll
add more functionality to this page, such as product recommendations.
Roadmap for This Chapter
• The following
figure previews
what you’ll
create at each
tier in this
chapter to
achieve a
functional
departments
list.
Roadmap for This Chapter
• To implement the departments list, you’ll start with the database
and make your way to the presentation tier:
1. You’ll create the Department table in the database. This table will
store data regarding the store’s departments. Before adding this
table, you’ll learn the basic concepts of working with relational
databases.
2. You’ll add the GetDepartments stored procedure to the database,
which (like all the other stored procedures you’ll write) is logically
located in the data tier part of the application. At this step, you’ll
learn how to speak with relational databases using SQL.
3. You’ll create the business tier components of the departments list.
You’ll learn how to communicate with the database by calling the
stored procedure and sending the results to the presentation tier.
4. Finally, you’ll implement the DepartmentsList.ascx Web User
Control to display a dynamic list of departments for your visitor,
which is the goal of this chapter.
Storing Catalog Information
Understanding Data Tables
This section is a quick database lesson that covers
the essential information you need to know to design
simple data tables. We’ll briefly discuss the main
parts that make up a database table:
• Primary keys
• Unique columns
• SQL Server data types
• Nullable columns and default values
• Identity columns
• Indexes
The Department Table
 The database element of the product catalog is composed
of tables, table relationships, and stored procedures.
Because this chapter only covers the departments list,
you’ll only need to create one data table: the Department
table. This table will store your departments’ data and is
one of the simplest tables you’ll work with.
 The table containing the departments’ data might look like
the following figure.
The Department Table
 Suppose you add another record to the Department table
shown previously in the following figure, making it look like the
table shown in previous figure.
 An alternative solution, and usually the preferred one, is to have
an additional column in the table, called an ID column, to act as
its primary key. With an ID column, the Department table would
look like as in the following figure.
Designing the Department Table
Creating the Department Table
1. Using the Database Explorer window in Visual Web Developer, open
the BalloonShop data connection that you created in the previous
Chapter. Remember, if Database Explorer is not visible, activate it using
View ➤ Database Explorer or by using the default shortcut
Ctrl+Alt+S.
2. Expand the BalloonShop database connection node, right-click the
Tables node, and select Add New Table from the context menu.
Alternatively, after connecting to the database, you can choose Data ➤
Add New ➤ Table.
3. A form appears where you can add columns to the new table. Using this
form, add three columns, with the properties described in the Table.
Choosing Technologies and Tools: Using ASP.NET 2.0
After adding these fields, the form should look like in the following figure in
Visual Studio.
Press Ctrl+S or select File ➤ Save Table1. When asked, type Department for
the table name.
Choosing Technologies and Tools: Using SQL Server 2005
After creating the table in the database, you can open it to add some data. To open
the Department table for editing, right-click it in Database Explorer and select
Show Table Data from the context menu. Using the integrated editor, you can start
adding rows. Because DepartmentID is an identity column, you cannot manually edit
its data-SQL Server automatically fills this field, depending on the identity seed and
identity increment values that you specified when creating the table.
Add two departments, as shown in the following figure .
Communicating with the Database
SELECT
The SELECT statement is used to query the
database and retrieve selected data that
match the criteria you specify. Its basic
structure is
SELECT <column list>
FROM <table name(s)>
[WHERE <restrictive condition>]
Communicating with the Database
The simplest SELECT command you can
execute on your BalloonShop database is
SELECT * FROM Department
SELECT DepartmentID, Name, Description
FROM Department
SELECT Name FROM Department
WHERE DepartmentID = 1
Communicating with the Database: SELECT
Communicating with the Database: INSERT
The INSERT statement is used to insert or
add a row of data into the table. Its syntax
is as follows:
INSERT [INTO] <table name> (column list)
VALUES (column values)
The following INSERT statement adds a department
named “Mysterious Department” to the Department table:
INSERT INTO Department (Name) VALUES
('Mysterious Department')
Communicating with the Database: UPDATE
The UPDATE statement is used to modify
existing data and has the following syntax:
UPDATE <table name>
SET <column name> = <new value>
[, <column name> = <new value> ...]
[WHERE <restrictive condition>]
Ex:
UPDATE Department SET Name='Cool
Department' WHERE DepartmentID = 43
Communicating with the Database: DELETE
The syntax of the DELETE command is actually very
simple:
DELETE [FROM] <table name>
[WHERE <restrictive condition>]
The FROM keyword is optional and can be omitted. We
generally use it because it makes the query sound more
like normal English. Most times, you’ll want to use the
WHERE clause to delete a single row:
DELETE FROM Department
WHERE DepartmentID = 43
Creating Stored Procedures
You need to create the GetDepartments stored procedure, which
returns department information from the Department table. This
stored procedure is part of the data tier and will be accessed from
the business tier. The final goal is to have this data displayed in
the user control.
The SQL code that retrieves the necessary data and that you
need to save to the database as the GetDepartments stored
procedure is the following:
SELECT DepartmentID, Name, Description FROM Department
This command returns all the department information.
Saving the Query As a Stored Procedure
The syntax for creating a stored procedure that has no
input or output parameters is as follows:
CREATE PROCEDURE <procedure name>
AS <stored procedure code>
Exercise: Writing the Stored Procedure
1. Make sure the data connection to the BalloonShop database is
expanded and selected in Database Explorer. Choose Data ➤
Add New ➤ Stored Procedure. Alternatively, you can rightclick the Stored Procedures node in Server Explorer and select
Add New Stored Procedure.
2. Replace the default text with your GetDepartments stored
procedure:
CREATE PROCEDURE GetDepartments AS
SELECT DepartmentID, Name, Description
FROM Department
3. Press Ctrl+S to save the stored procedure. Unlike with the
tables, you won’t be asked for a name because the database
already knows that you’re talking about the GetDepartments
stored procedure.
4. Right Click at the stored procedure, and Click Execute
Exercise: Execute the Stored Procedure
Exercise: Execute the Stored Procedure
4.
Now test your first stored procedure to
see that it’s actually working. Navigate
to the GetDepartments stored
procedure node in Database Explorer
and select Execute, as shown in the
following Figure.
Adding Logic to the Site
The business tier (or middle tier) is said to be the brains of the application
because it manages the application’s business logic.
For the business tier of the departments list, you’ll implement three classes:
1. GenericDataAccess implements common functionality that you’ll then reuse
whenever you need to access the database. Having this kind of generic
functionality packed in a separate class saves keystrokes and avoids bugs
in the long run.
2. CatalogAccess contains product catalog specific functionality, such the
GetDepartments method that will retrieve the list of departments from the
database.
3. BalloonShopConfiguration and Utilities contain miscellaneous functionality
such as sending emails, which will be reused in various places in
BalloonShop.
Connecting to SQL Server
Each database operation always consists of three steps:
1. Open a connection to the SQL Server database.
2. Perform the needed operations with the database and
get back the results.
3. Close the connection to the database.
The class used to connect to SQL Server is SqlConnection. When
creating a new database connection, you always need to specify
at least three important pieces of data:
1. The name of the SQL Server instance you’re connecting to
2. The authentication information that will permit you to access
the server
3. The database you want to work with
Connecting to SQL Server
• The following code snippet demonstrates how to
create and open a database connection:
// Create the connection object
SqlConnection connection = new SqlConnection();
// Set the connection string
connection.ConnectionString =
"Server=(local)\SqlExpress; " +
"User ID=hassanin; Password=CS483;" +
"Database=BalloonShop";
// Open the connection
connection.Open();
Issuing Commands and Executing Stored Procedures
Creating an SqlCommand Object
// Create the command object
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandText = "GetDepartments";
command.CommandType = CommandType.
StoredProcedure;
This is equivalent to:
// Create the command object
SqlCommand command = new
SqlCommand("GetDepartments", connection);
command.CommandType =
CommandType.StoredProcedure;
Executing the Command and Closing the Connection
• Here’s a simple example of reading some records
from the database and saving them to a DataTable:
// Open the connection
conn.Open();
// Create the SqlDataReader object by executing the command
SqlDataReader reader = comm.ExecuteReader();
// Create a new DataTable and populate it from the SqlDataReader
DataTable table = new DataTable();
table.Load(reader);
// Close the reader and the connection
reader.Close();
conn.Close();
Implementing Generic Data Access Code
The .NET Framework ships with Managed Data
Providers for
SQL Server (System.Data.SqlClient namespaces),
Oracle (System.Data.Oracle),
OLE DB (System.Data.OleDb), and
ODBC (System.Data.Odbc).
Create Database Exercise
Before we continue, please:
Create an Access table (for your personal
information), and do the following:
1- Display the contents in the Web page(Master
page).
2- Follow the steps to create Data List.
Implementing Generic Data Access Code
// Create a new database provider factory
DbProviderFactory factory =DbProviderFactories.GetFactory("System.Data.SqlClient");
// Create the connection object
DbConnection conn = factory.CreateConnection();
// Initialize the connection string
conn.ConnectionString = "... connection string ...";
// Create the command object and set its properties
DbCommand comm = conn.CreateCommand();
comm.CommandText = "GetDepartments";
comm.CommandType = CommandType.StoredProcedure;
// Open the connection
conn.Open();
// Execute the command and save the results in a DataTable
DbDataReader reader = comm.ExecuteReader();
DataTable table = new DataTable();
table.Load(reader);
// Close the reader and the connection
reader.Close();
conn.Close();
Sending Emails
SMTP (Simple Mail Transfer Protocol)
•
The standard code that sends an email looks like the following
code snippet (you need to replace the text in italics with your
own data):
// Configure mail client (may need additional code for
// authenticated SMTP servers)
SmtpClient smtpClient = new SmtpClient("SMTP server address");
// Create the mail message
MailMessage mailMessage = new MailMessage("from", "to",
"subject", "body");
// Send mail
smtpClient.Send(mailMessage);
Writing the Business Tier Code
You ‘ll add the following C# classes:
•
•
•
•
GenericDataAccess contains the generic database access
code, implementing basic error-handling and logging
functionality.
CatalogAccess contains the product catalog business logic.
BalloonShopConfiguration provides easy access to various
configuration settings (that are generally read from
web.config), such as the database connection string, and so
on.
Utilities contains miscellaneous functionality such as sending
emails, which will be used from various places in BalloonShop.
Exercise: Implementing the Data Access Code
1. Open the web.config configuration file (double-click on its
name in Solution Explorer) and update the connectionStrings
element like this:
<configuration
xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
<appSettings/>
<connectionStrings>
<add name="BalloonShopConnection" connectionString="Server=
(local)\SqlExpress;
Integrated Security=True;Database=BalloonShop"
providerName="System.Data.SqlClient"/>
</connectionStrings>
<system.web>
<!--
Exercise: Implementing the Data Access Code
2. Add the other necessary configuration data under the
<appSettings> node in web.config, as shown here:
<appSettings>
<add key="MailServer" value="localhost" />
<add key="EnableErrorLogEmail" value="true" />
<add key="ErrorLogEmail"
value="[email protected]" />
</appSettings>
Exercise: Implementing the Data Access Code
3. Right-click the project’s name in Solution Explorer and
choose Add New Item from the context menu.
4. Choose the Class template, and set its name to
ApplicationConfiguration.cs. Click Add.
5. You’ll be asked about adding the class into the
App_Code folder. This is a special folder in ASP.NET
2.0. Choose Yes.
6. Modify the ApplicationConfiguration class like this:
Exercise: Implementing the Data Access Code
using System;
using System.Configuration;
public static class BalloonShopConfiguration
{
// Caches the connection string
private static string dbConnectionString;
// Caches the data provider name
private static string dbProviderName;
static BalloonShopConfiguration()
{
dbConnectionString =ConfigurationManager.ConnectionStrings
["BalloonShopConnection"].ConnectionString;
dbProviderName =ConfigurationManager.ConnectionStrings
["BalloonShopConnection"].ProviderName;
}
Exercise: Implementing the Data Access Code
// Returns the connection string for the BalloonShop database
public static string DbConnectionString
{
get
{
return dbConnectionString;
}
}
// Returns the data provider name
public static string DbProviderName
{
get
{
return dbProviderName;
}
}
Exercise: Implementing the Data Access Code
// Returns the address of the mail server
public static string MailServer
{
get
{
return ConfigurationManager.AppSettings["MailServer"];
}
}
// Send error log emails?
public static bool EnableErrorLogEmail
{
get
{
return bool.Parse(ConfigurationManager.AppSettings
["EnableErrorLogEmail"]);
}
}
Exercise: Implementing the Data Access Code
// Returns the email address where to send error reports
public static string ErrorLogEmail
{
get
{
return ConfigurationManager.AppSettings["ErrorLogEmail"];
}
}
}
7. Right-click the project’s name in Solution Explorer and choose Add New
Item from the context menu.
8. Choose the Class template and set its name to Utilities.cs. Click Add. You’ll
be asked about adding the class into the App_Code folder. Choose Yes.
9. Write the following code into Utilities.cs (note that we’ve removed the
unnecessary using statements):
using System;
using System.Net.Mail;
Exercise: Implementing the Data Access Code
public static class Utilities
{
static Utilities()
{
// TODO: Add constructor logic here
}
// Generic method for sending emails
public static void SendMail(string from, string to, string subject,
string body)
{
// Configure mail client (may need additional code for authenticated SMTP servers)
SmtpClient mailClient = new SmtpClient
(BalloonShopConfiguration.MailServer);
// Create the mail message
MailMessage mailMessage = new MailMessage(from, to, subject, body);
Exercise: Implementing the Data Access Code
/*
// For SMTP servers that require authentication
message.Fields.Add
("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", 1);
message.Fields.Add
("http://schemas.microsoft.com/cdo/configuration/sendusername",
"SmtpHostUserName");
message.Fields.Add
("http://schemas.microsoft.com/cdo/configuration/sendpassword",
"SmtpHostPassword");
*/
// Send mail
mailClient.Send(mailMessage);
}
Exercise: Implementing the Data Access Code
// Send error log mail
public static void LogError(Exception ex)
{
// get the current date and time
string dateTime = DateTime.Now.ToLongDateString() + ", at "
+ DateTime.Now.ToShortTimeString();
// stores the error message
string errorMessage = "Exception generated on " + dateTime;
// obtain the page that generated the error
System.Web.HttpContext context = System.Web.HttpContext.Current;
errorMessage += "\n\n Page location: " + context.Request.RawUrl;
// build the error message
errorMessage += "\n\n Message: " + ex.Message;
errorMessage += "\n\n Source: " + ex.Source;
errorMessage += "\n\n Method: " + ex.TargetSite;
errorMessage += "\n\n Stack Trace: \n\n" + ex.StackTrace;
// send error email in case the option is activated in Web.Config
if (BalloonShopConfiguration.EnableErrorLogEmail)
Exercise: Implementing the Data Access Code
if (BalloonShopConfiguration.EnableErrorLogEmail)
{
string from = "[email protected]";
string to = BalloonShopConfiguration.ErrorLogEmail;
string subject = BalloonShopConfiguration.SiteName + " error
report";
string body = errorMessage;
SendMail(from, to, subject, body);
}
}
}
Exercise: Implementing the Data Access Code
10. Right-click the project’s name in Solution Explorer and choose Add New
Item from the context menu. Choose the Class template and set its name to
GenericDataAccess.cs. Click Add. You’ll be asked about adding the class
into the App_Code folder. Choose Yes.
11. Write the following code into GenericDataAccess.cs:
using System;
using System.Data;
using System.Data.Common;
using System.Configuration;
public static class GenericDataAccess
{
// static constructor
static GenericDataAccess()
{
// TODO: Add constructor logic here
}
Exercise: Implementing the Data Access Code
// executes a command and returns the results as a DataTable object
public static DataTable ExecuteSelectCommand(DbCommand command)
{
// The DataTable to be returned
DataTable table;
// Execute the command making sure the connection gets closed in the end
try
{
// Open the data connection
command.Connection.Open();
// Execute the command and save the results in a DataTable
DbDataReader reader = command.ExecuteReader();
table = new DataTable();
table.Load(reader);
Exercise: Implementing the Data Access Code
// Close the reader
reader.Close();
}
catch (Exception ex)
{ Utilities.LogError(ex);
throw ex;
}
finally
{
// Close the connection
command.Connection.Close();
}
return table;
}
public static DbCommand CreateCommand()
{
// Obtain the database provider name
string dataProviderName = BalloonShopConfiguration.DbProviderName;
Exercise: Implementing the Data Access Code
// Obtain the database connection string
string connectionString = BalloonShopConfiguration.DbConnectionString;
// Create a new data provider factory
DbProviderFactory factory = DbProviderFactories.
GetFactory(dataProviderName);
// Obtain a database specific connection object
DbConnection conn = factory.CreateConnection();
// Set the connection string
conn.ConnectionString = connectionString;
// Create a database specific command object
DbCommand comm = conn.CreateCommand();
// Set the command type to stored procedure
comm.CommandType = CommandType.StoredProcedure;
// Return the initialized command object
return comm;
}
}
Exercise: Implementing the Data Access Code
12. In Solution Explorer, right-click on the App_Code folder and choose Add New Item.
Using the window that appears, create a new class named CatalogAccess (which
would reside in a file named CatalogAccess.cs). Add the new code to the file:
using System;
using System.Data;
using System.Data.Common;
public static class CatalogAccess
{
static CatalogAccess()
{
// TODO: Add constructor logic here
}
// Retrieve the list of departments
public static DataTable GetDepartments()
{
// get a configured DbCommand object
DbCommand comm = GenericDataAccess.CreateCommand();
// set the stored procedure name
comm.CommandText = "GetDepartments";
// execute the stored procedure and return the results
return GenericDataAccess.ExecuteSelectCommand(comm);
}
How It Works: The Business Tier
•
•
•
•
•
•
The configuration file web.config is an external configuration XML file
managed by ASP.NET. This powerful file can include many options
regarding the application’s security, performance, behavior, and so on.
Saving data to web.config is beneficial because you can change it
independently of your C# code, which now doesn’t need to be recompiled
when you change the address of the mail server or the database
connection string.
Then, you added the BalloonShopConfiguration class, which is simply a
collection of static properties that return data from web.config. The
performance is improved as well because the class can cache the values
read from web.config instead of reading them on every request.
Next, you implemented the GenericDataAccess class, whose purpose is to
store a series of common database access operations, to avoid typing it all
over again in other places.
CreateCommand creates a DbCommand object, sets some standard
properties to it, and returns the configured object.
ExecuteSelectCommand is essentially a wrapper for DbCommand’s
ExecuteReader method, except it returns the results as a DataTable
instead of a DataReader.
Understand the OOP Terminology
Understanding of basic OOP terminology-such as
classes, objects, constructors, methods, properties,
fields, instance members and static members, public
data and private data, and so on-is an important
prerequisite for this course. These topics are
covered in many articles on the Internet, such as the
ones you can find for free download
at http://www.cristiandarie.ro/downloads.html .
How It Works: The Business Tier
•
We’ve chosen to use static members mainly to improve performance. Because
static classes and static members are initialized only once, they don’t need to be
reinstantiated each time a new visitor makes a new request; instead, their “global”
instances are used. In the presentation tier, you’ll display your list of departments
with a call like this:
list.DataSource = CatalogAccess.GetDepartments();
If GetDepartments would have been an instance method, you
would have needed to create a separate instance of the
CatalogAccess class instead of using the static instance,
which would have had, obviously, a bigger performance
impact:
CatalogAccess catalogAccess = new CatalogAccess();
list.DataSource = catalogAccess.GetDepartments();
Displaying the List of Departments
•
•
Now that everything is in place in the other tiers, all you have to do is create the
presentation tier part—the final goal you’ve been working toward from the
beginning. As you saw in the figures at the beginning of this chapter, the
departments list needs to look something like the following figure when the site is
loaded in the web browser.
Fortunately, the .NET Framework provides a few useful web controls that can help
you solve this problem without writing too much code. For example, the DataList
control can be set to simply take a DataTable object as input and generate content
based on it.
•Before actually writing the user control, let’s prepare the BalloonShop CSS file.
How It Works: The Business Tier
•
We’ve chosen to use static members mainly to improve performance. Because
static classes and static members are initialized only once, they don’t need to be
reinstantiated each time a new visitor makes a new request; instead, their “global”
instances are used. In the presentation tier, you’ll display your list of departments
with a call like this:
list.DataSource = CatalogAccess.GetDepartments();
If GetDepartments would have been an instance method, you
would have needed to create a separate instance of the
CatalogAccess class instead of using the static instance,
which would have had, obviously, a bigger performance
impact:
CatalogAccess catalogAccess = new CatalogAccess();
list.DataSource = catalogAccess.GetDepartments();
Downloading the Code
• The code for this book is available for
download in the Source Code area of
the Apress web site:
http://www.apress.com
• Unzip the file and open Welcome.html
for installation details.
Quiz # 1
• Design an interface for e-Learning
Application, includes the following:
• Faculty Name.
• Department Names.
• Courses Content.