说明:该实例基于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; 600px; } .divBorder { border-style:dashed; border-thin; } .tb { 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 }