说明:该实例基于ASP.NET3.5使用Session实现购物车功能,数据库使用SqlServer2005。商品的分类以及产品的管理功能不在此实现。
希望该实例能对对购物车功能实现不太清楚的开发人员起到抛砖引玉的功效:)。
文中的产品图片来源于互联网。
1、惯例——预览功能
产品列表:当点击每个产品下的添加到购物车图片时,页面会转向到ShoppingCart.aspx同时传递一个当前产品的ID参数。
购物车:根据ID获取数据添加到DataTable,用Session存储,如果产品ID存在则不添加。
2、Products表设计
Product表模拟数据
3、数据访问类SqlHelper.cs
类图:
代码:
using System;
using
System.Data;
using
System.Data.SqlClient;
namespace
DAO
{
public
class
SqlHelper
{
//
从Web.config中读取数据库连接字符春
private
String ConnStr
=
System.Configuration.ConfigurationSettings.AppSettings[
"
ConnString
"
];
private
SqlConnection conn
=
null
;
///
<summary>
///
将查询结果集填充到DataTable
///
</summary>
///
<param name="query">
查询T-Sql
</param>
///
<returns></returns>
public
DataTable FillDataTable(String query)
{
DataTable dt
=
new
DataTable();
using
(conn
=
new
SqlConnection(ConnStr))
{
SqlCommand cmd
=
new
SqlCommand();
cmd.Connection
=
conn;
cmd.CommandText
=
query;
SqlDataAdapter ada
=
new
SqlDataAdapter();
ada.SelectCommand
=
cmd;
ada.Fill(dt);
}
return
dt;
}
///
<summary>
///
将查询结果集填充到DataSet
///
</summary>
///
<param name="query">
查询T-Sql,可以是多个Select语句
</param>
///
<returns></returns>
public
DataSet FillDataSet(String query)
{
DataSet ds
=
new
DataSet();
using
(conn
=
new
SqlConnection(ConnStr))
{
SqlCommand cmd
=
new
SqlCommand();
cmd.Connection
=
conn;
cmd.CommandText
=
query;
SqlDataAdapter ada
=
new
SqlDataAdapter();
ada.SelectCommand
=
cmd;
ada.Fill(ds);
}
return
ds;
}
///
<summary>
///
执行insert、update、delete、truncate语句
///
</summary>
///
<param name="commandText">
insert、update、delete、truncate语句
</param>
public
void
ExecuteNonQuery(String commandText)
{
using
(conn
=
new
SqlConnection(ConnStr))
{
SqlTransaction tran
=
conn.BeginTransaction();
try
{
SqlCommand cmd
=
new
SqlCommand();
cmd.Connection
=
conn;
cmd.Transaction
=
tran;
cmd.CommandText
=
commandText;
conn.Open();
cmd.ExecuteNonQuery();
tran.Commit();
}
catch
{
tran.Rollback();
}
finally
{
tran.Dispose();
}
}
}
}
}
4、产品列表功能实现ProductList.aspx
前台页面
DataList:显示产品列表
HyperLink:翻页
代码:
<%
@ Page Language
=
"
C#
"
AutoEventWireup
=
"
true
"
CodeFile
=
"
ProductList.aspx.cs
"
Inherits
=
"
ProductList
"
%>
<!
DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
>
<
html
xmlns
="http://www.w3.org/1999/xhtml"
>
<
head
runat
="server"
>
<
title
>
浏览产品列表
</
title
>
<
link
href
="CSS/buy.css"
rel
="stylesheet"
type
="text/css"
/>
</
head
>
<
body
>
<
form
id
="form1"
runat
="server"
>
<
div
id
="zone"
>
<
div
align
="right"
class
="divBorder"
>
<
a
href
="ShoppingCart.aspx"
>
<
img
src
="Images/cart.jpg"
alt
="我的购物车"
border
="0"
title
="查看购物车"
/></
a
>
</
div
>
<
br
/>
<
div
>
<
asp:Button
ID
="btnRedirect"
runat
="server"
Text
="翻页很累,在火星可以显示所有产品"
onclick
="btnRedirect_Click"
/>
</
div
>
<
br
/>
<
div
align
="center"
class
="divBorder"
>
<
asp:DataList
ID
="dlProducts"
runat
="server"
RepeatColumns
="3"
RepeatDirection
="Horizontal"
OnItemDataBound
="dlProducts_ItemDataBound"
Width
="99%"
>
<
ItemTemplate
>
<
div
>
<
asp:Image
ID
="imgPic"
runat
="server"
/>
</
div
>
<
div
>
<%
#
Eval
(
"
ProductName
"
)
%>
</
div
>
<
div
>
<
font
color
="gray"
><
s
>
<%
# Convert.ToInt32(
Eval
(
"
MarketPrice
"
)).ToString(
"
c2
"
)
%>
</
s
></
font
>
<
font
color
="red"
>
<%
# Convert.ToInt32(
Eval
(
"
BuyPrice
"
)).ToString(
"
c2
"
)
%>
</
font
>
</
div
>
<
div
>
<
a
href
='ShoppingCart.aspx?ID=<%#
Eval("ID")%
>
&ProductNo
=
<%
#
Eval
(
"
ProductNo
"
)
%>
'>
<
img
src
="Images/addtocart.png"
alt
="添加到购物车"
border
="0"
title
="添加到购物车"
/>
</
a
>
</
div
>
</
ItemTemplate
>
</
asp:DataList
>
</
div
>
<
br
/>
<
div
class
="divBorder"
>
<
asp:Label
ID
="lblCurrentPage"
runat
="server"
></
asp:Label
>
/
<
asp:Label
ID
="lblPageCount"
runat
="server"
></
asp:Label
>
页
<
asp:HyperLink
ID
="lnkFirst"
runat
="server"
>
首页
</
asp:HyperLink
>
<
asp:HyperLink
ID
="lnkPrev"
runat
="server"
>
上页
</
asp:HyperLink
>
<
asp:HyperLink
ID
="lnkNext"
runat
="server"
>
下页
</
asp:HyperLink
>
<
asp:HyperLink
ID
="lnkLast"
runat
="server"
>
末页
</
asp:HyperLink
>
</
div
>
</
div
>
</
form
>
</
body
>
</
html
>
用到的CSS代码:
body
{
font-size
:
14px
;
text-align
:
center
;
}
#zone
{
margin
:
0 auto
;
width
:
600px
;
}
.divBorder
{
border-style
:
dashed
;
border-width
:
thin
;
}
.tb
{
width
:
30px
;
}
PS:页面中关于价格的数字颜色和样式,请用CSS实现
后台代码:
using
System;
using
System.Web.UI.WebControls;
using
DAO;
using
System.Data;
public
partial
class
ProductList : System.Web.UI.Page
{
protected
void
Page_Load(
object
sender, EventArgs e)
{
if
(
!
IsPostBack)
{
this
.BindList();
}
}
private
void
BindList()
{
SqlHelper helper
=
new
SqlHelper();
PagedDataSource pds
=
new
PagedDataSource();
pds.DataSource
=
helper.FillDataTable(
"
Select * From Products Order By ID DESC
"
).DefaultView;
pds.AllowPaging
=
true
;
if
(Request.QueryString[
"
P
"
]
!=
null
)
{
pds.PageSize
=
((DataView)pds.DataSource).Table.Rows.Count;
btnRedirect.Text
=
"
浏览器发飙了,赶紧回地球吧
"
;
}
else
{
pds.PageSize
=
6
;
btnRedirect.Text
=
"
翻页很累,在火星可以显示所有产品
"
;
}
int
CurrentPage;
if
(Request.QueryString[
"
Page
"
]
!=
null
)
{
CurrentPage
=
Convert.ToInt32(Request.QueryString[
"
Page
"
]);
}
else
{
CurrentPage
=
1
;
}
pds.CurrentPageIndex
=
CurrentPage
-
1
;
lblCurrentPage.Text
=
CurrentPage.ToString();
lblPageCount.Text
=
pds.PageCount.ToString();
if
(
!
pds.IsFirstPage)
{
lnkPrev.NavigateUrl
=
Request.CurrentExecutionFilePath
+
"
?Page=
"
+
Convert.ToInt32(CurrentPage
-
1
);
lnkFirst.NavigateUrl
=
Request.CurrentExecutionFilePath
+
"
?Page=1
"
;
}
if
(
!
pds.IsLastPage)
{
lnkNext.NavigateUrl
=
Request.CurrentExecutionFilePath
+
"
?Page=
"
+
Convert.ToInt32(CurrentPage
+
1
);
lnkLast.NavigateUrl
=
Request.CurrentExecutionFilePath
+
"
?Page=
"
+
pds.PageCount;
}
dlProducts.DataSource
=
pds;
dlProducts.DataBind();
}
protected
void
dlProducts_ItemDataBound(
object
sender, DataListItemEventArgs e)
{
if
(e.Item.ItemType
==
ListItemType.Item
||
e.Item.ItemType
==
ListItemType.AlternatingItem)
{
DataRowView drv
=
(DataRowView)e.Item.DataItem;
((Image)e.Item.FindControl(
"
imgPic
"
)).ImageUrl
=
"
~/Images/Products/
"
+
drv[
"
PicturePath
"
].ToString();
}
}
protected
void
btnRedirect_Click(
object
sender, EventArgs e)
{
if
(btnRedirect.Text
==
"
翻页很累,在火星可以显示所有产品
"
)
{
Response.Redirect(
"
ProductList.aspx?P=1
"
);
}
else
{
Response.Redirect(
"
ProductList.aspx
"
);
}
}
}
5、购物车功能实现ShoppingCart.aspx
前台页面:
<%
@ Page Language
=
"
C#
"
AutoEventWireup
=
"
true
"
CodeFile
=
"
ShoppingCart.aspx.cs
"
Inherits
=
"
ShoppingCart
"
%>
<!
DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
>
<
html
xmlns
="http://www.w3.org/1999/xhtml"
>
<
head
runat
="server"
>
<
title
>
我的购物车
</
title
>
<
link
href
="CSS/buy.css"
rel
="stylesheet"
type
="text/css"
/>
<
script
type
="text/javascript"
>
//
点击+号图,数量+1
function
Plus(obj) {
obj.value
=
parseInt(obj.value)
+
1
;
}
//
数量-1
function
Reduce(obj) {
if
(obj.value
>
1
) {
obj.value
=
obj.value
-
1
;
}
}
//
替换txtAmount文本框非整数的输入
//
数据整个不合法时置1
function
CheckValue(obj) {
var
v
=
obj.value.replace(
/
[^\d]
/
g,
''
);
if
(v
==
''
||
v
==
'
NaN
'
) {
obj.value
=
"
1
"
;
}
else
{
obj.value
=
v;
}
}
</
script
>
</
head
>
<
body
>
<
form
id
="form1"
runat
="server"
>
<
div
id
="zone"
>
<
div
align
="left"
class
="divBorder"
>
<
img
src
="Images/back.jpg"
onclick
="javascript:location.href='ProductList.aspx';"
style
="cursor: hand"
alt
="返回产品列表"
border
="0"
title
="返回产品列表"
/>
<
img
src
="Images/cart_001.gif"
alt
="我的购物车"
/>
</
div
>
<
br
/>
<
div
class
="divBorder"
>
<
asp:GridView
ID
="gvCart"
runat
="server"
DataKeyNames
="ID"
AutoGenerateColumns
="False"
ShowFooter
="True"
Width
="98%"
OnRowDataBound
="gvCart_RowDataBound"
OnRowDeleting
="gvCart_RowDeleting"
>
<
Columns
>
<
asp:BoundField
DataField
="ProductNo"
HeaderText
="产品编号"
>
<
ItemStyle
Width
="80px"
/>
</
asp:BoundField
>
<
asp:BoundField
DataField
="ProductName"
HeaderText
="产品名称"
/>
<
asp:TemplateField
HeaderText
="产品单价"
>
<
ItemStyle
Width
="80px"
/>
<
ItemTemplate
>
<%
# Convert.ToInt32(
Eval
(
"
BuyPrice
"
)).ToString(
"
c2
"
)
%>
</
ItemTemplate
>
</
asp:TemplateField
>
<
asp:TemplateField
HeaderText
="数量"
>
<
ItemStyle
Width
="80px"
/>
<
ItemTemplate
>
<
img
src
="Images/bag_close.gif"
id
="imgReduce"
runat
="server"
/>
<
asp:TextBox
ID
="txtAmount"
Width
="20px"
Height
="16px"
runat
="server"
Text
='<%#
Eval("Amount") %
>
'
onkeyup="CheckValue(this)">
</
asp:TextBox
>
<
img
src
="Images/bag_open.gif"
id
="imgPlus"
runat
="server"
/>
</
ItemTemplate
>
</
asp:TemplateField
>
<
asp:CommandField
HeaderText
="删除"
DeleteText
="删除"
ShowDeleteButton
="true"
>
<
ItemStyle
Width
="30px"
/>
</
asp:CommandField
>
</
Columns
>
<
EmptyDataTemplate
>
您的购物车中没有任何商品。
</
EmptyDataTemplate
>
<
AlternatingRowStyle
BackColor
="WhiteSmoke"
/>
</
asp:GridView
>
</
div
>
<
br
/>
<
div
>
<
a
href
="ProductList.aspx"
>
<
img
src
="Images/go_on.gif"
border
="0"
/></
a
>
<
asp:ImageButton
ID
="imgbtnTotal"
runat
="server"
ImageUrl
="~/Images/updatecart.gif"
OnClick
="imgbtnTotal_Click"
/>
<
img
src
="Images/pay.gif"
/>
</
div
>
</
div
>
</
form
>
</
body
>
</
html
>
后台代码:
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Web;
using
System.Web.UI;
using
System.Web.UI.WebControls;
using
System.Web.UI.HtmlControls;
using
System.Data;
using
DAO;
using
System.Drawing;
public
partial
class
ShoppingCart : System.Web.UI.Page
{
//
整型变量,用于存储总金额
private
Int32 Total
=
0
;
protected
void
Page_Load(
object
sender, EventArgs e)
{
if
(
!
IsPostBack)
{
BindCartList();
}
}
private
void
BindCartList()
{
DataTable dt
=
new
DataTable();
//
如果Session变量存在,则直接获取
if
(Session[
"
Cart
"
]
!=
null
)
{
dt
=
(DataTable)Session[
"
Cart
"
];
}
else
//
如果Session变量不存在,创建存储数据的表结构
{
dt.Columns.Add(
new
DataColumn(
"
ID
"
,
typeof
(Int32)));
dt.Columns.Add(
new
DataColumn(
"
ProductNo
"
,
typeof
(String)));
dt.Columns.Add(
new
DataColumn(
"
ProductName
"
,
typeof
(String)));
dt.Columns.Add(
new
DataColumn(
"
BuyPrice
"
,
typeof
(String)));
dt.Columns.Add(
new
DataColumn(
"
Amount
"
,
typeof
(Int32)));
}
//
ID或ProductNo不为null
//
则表示选中一件商品添加到购物车
if
(ID
!=
null
)
{
//
先判断购物车中是否已经存在该商品
Boolean IsExist
=
false
;
foreach
(DataRow dr
in
dt.Rows)
{
if
(dr[
"
ProductNo
"
].ToString()
==
ProductNo)
{
IsExist
=
true
;
break
;
}
}
//
如果购物车中存在该商品,则提示客户
//
该商品不会被重复添加到购物车
if
(IsExist)
{
ScriptManager.RegisterStartupScript(
this
,
typeof
(Page),
"
alertExist
"
,
"
alert('您选择的商品(编号:
"
+
ProductNo
+
"
)已在购物车存在!')
"
,
true
);
}
else
//
如果购物车中不存在该商品,则添加到购物车
{
SqlHelper helper
=
new
SqlHelper();
DataTable dtRow
=
helper.FillDataTable(
String.Format(
"
Select * From Products Where ID={0}
"
, ID.ToString()));
dt.Rows.Add(
new
object
[]{
Convert.ToInt32(ID.ToString()),
dtRow.Rows[
0
][
"
ProductNo
"
].ToString(),
dtRow.Rows[
0
][
"
ProductName
"
].ToString(),
Convert.ToInt32(dtRow.Rows[
0
][
"
BuyPrice
"
].ToString()),
1
});
}
}
gvCart.DataSource
=
dt;
gvCart.DataBind();
Session[
"
Cart
"
]
=
dt;
}
protected
void
gvCart_RowDataBound(
object
sender, GridViewRowEventArgs e)
{
if
(e.Row.RowType
==
DataControlRowType.DataRow)
{
//
GridView行的加亮显示功能
e.Row.Attributes.Add(
"
onmouseover
"
,
"
b=this.style.backgroundColor;this.style.backgroundColor='#E1ECEE'
"
);
e.Row.Attributes.Add(
"
onmouseout
"
,
"
this.style.backgroundColor=b
"
);
//
给+号图片和-号图片添加客户端click事件
//
用JavaScript实现数量的+1和-1
TextBox tb
=
(TextBox)e.Row.FindControl(
"
txtAmount
"
);
((HtmlImage)e.Row.FindControl(
"
imgReduce
"
)).Attributes.Add(
"
onclick
"
,
"
Reduce(
"
+
tb.ClientID
+
"
)
"
);
((HtmlImage)e.Row.FindControl(
"
imgPlus
"
)).Attributes.Add(
"
onclick
"
,
"
Plus(
"
+
tb.ClientID
+
"
)
"
);
//
根据商品单价和数量计算购物车中商品的总金额
DataRowView drv
=
(DataRowView)e.Row.DataItem;
Total
+=
Int32.Parse(drv[
"
BuyPrice
"
].ToString())
*
Int32.Parse(tb.Text);
}
if
(e.Row.RowType
==
DataControlRowType.Footer)
{
//
将总金额显示在金额一列对应的Footer单元格
e.Row.Cells[
1
].Text
=
"
金额总计:
"
;
e.Row.Cells[
1
].HorizontalAlign
=
HorizontalAlign.Right;
e.Row.Cells[
2
].Text
=
Total.ToString(
"
c2
"
);
e.Row.Cells[
2
].ForeColor
=
Color.Red;
}
}
protected
void
gvCart_RowDeleting(
object
sender, GridViewDeleteEventArgs e)
{
//
点击删除时从DataTable中删除对应的数据行
if
(Session[
"
Cart
"
]
!=
null
)
{
DataTable dt
=
(DataTable)Session[
"
Cart
"
];
dt.Rows.RemoveAt(e.RowIndex);
dt.AcceptChanges();
Session[
"
Cart
"
]
=
dt;
Response.Redirect(
"
ShoppingCart.aspx
"
);
}
}
protected
void
imgbtnTotal_Click(
object
sender, ImageClickEventArgs e)
{
//
遍历GridView,根据每行的文本框中的值
//
修改DataTable中对应行中数量一列的值
if
(Session[
"
Cart
"
]
!=
null
)
{
DataTable dt
=
(DataTable)Session[
"
Cart
"
];
for
(
int
i
=
0
; i
<
gvCart.Rows.Count; i
++
)
{
dt.Rows[i][
"
Amount
"
]
=
((TextBox)gvCart.Rows[i].FindControl(
"
txtAmount
"
)).Text;
}
dt.AcceptChanges();
Session[
"
Cart
"
]
=
dt;
Response.Redirect(
"
ShoppingCart.aspx
"
);
}
}
#region
属性
///
<summary>
///
get URL参数ID的值,定义为Nullable
<Int32>
类型
///
</summary>
private
Int32
?
ID
{
get
{
try
{
return
Int32.Parse(Request.QueryString[
"
ID
"
]);
}
catch
{
return
null
;
}
}
}
///
<summary>
///
get URL参数ProductNo的值
///
</summary>
private
String ProductNo
{
get
{
return
Request.QueryString[
"
ProductNo
"
];
}
}
#endregion
}