ASP.NET Starter Kit 挖寶記專欄:
進階開發篇:Commerce Starter Kit 可抄的寶在那裡?
作者:周世雄
2003 年 12 月
本文說明如何使用美國微軟公司所開發、免費、又開放原始程式碼的 ASP.NET Starter Kit 中之 Commerce Starter Kit (電子商務入門套件),適合程式設計師 (Developer) 學習線上購物的設計技巧。
加入商品到購物車動作原理
加入商品到購物車時執行 AddToCart.aspx,當網頁載入時將執行 Page_Load(),其中呼叫 ShoppingCartDB.vb 的 GetShoppingCartId() 取得使用者的 shopping cart ID,再呼叫 AddItem() 加商品資料到購物車資料庫:
'新增商品項目到購物車
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles MyBase.Load
If Not Request.Params("ProductID") Is Nothing Then
Dim cart As ASPNET.StarterKit.Commerce.ShoppingCartDB =
New ASPNET.StarterKit.Commerce.ShoppingCartDB()
'取得使用者的shopping cart ID
Dim cartId As String = cart.GetShoppingCartId()
'新增商品項目到購物車
cart.AddItem(cartId, CInt(Request.Params("ProductID")), 1)
End If
Response.Redirect("ShoppingCart.aspx")
End Sub
其中 ShoppingCartDB.vb 的 AddItem() 執行預存程序 CMRC_ShoppingCartAddItem,加資料到購物車資料庫:
Public Sub AddItem(ByVal cartID As String, ByVal productID As Integer, ByVal quantity As Integer)
'由Web.Config取得資料庫連線字串, 設定預存程序名稱
Dim myConnection As SqlConnection =
New SqlConnection(ConfigurationSettings.AppSettings("ConnectionString"))
Dim myCommand As SqlCommand = New SqlCommand("CMRC_ShoppingCartAddItem", myConnection)
'設定命令為預存程序
myCommand.CommandType = CommandType.StoredProcedure
'輸入預存程序輸入參數值
Dim parameterProductID As SqlParameter = New SqlParameter("@ProductID", SqlDbType.Int, 4)
parameterProductID.Value = productID
myCommand.Parameters.Add(parameterProductID)
Dim parameterCartID As SqlParameter = New SqlParameter("@CartID", SqlDbType.NVarChar, 50)
parameterCartID.Value = cartID
myCommand.Parameters.Add(parameterCartID)
Dim parameterQuantity As SqlParameter = New SqlParameter("@Quantity", SqlDbType.Int, 4)
parameterQuantity.Value = quantity
myCommand.Parameters.Add(parameterQuantity)
'連線資料庫並執行預存程序
myConnection.Open()
myCommand.ExecuteNonQuery()
myConnection.Close()
End Sub
預存程序 CMRC_ShoppingCartAddItem,若購物車已經有此商品則更新數量,若購物車尚無此商品則新增記錄到 CMRC_ShoppingCart 資料表中:
0 /* 若購物車已經有此商品則更新數量 */
UPDATE CMRC_ShoppingCart
SET Quantity = (@Quantity + CMRC_ShoppingCart.Quantity)
WHERE ProductID = @ProductID AND CartID = @CartID
ELSE /* 若購物車尚無此商品則新增記錄 */
INSERT INTO CMRC_ShoppingCart(CartID, Quantity, ProductID)
VALUES(@CartID, @Quantity, @ProductID)
GO
-->
CREATE Procedure CMRC_ShoppingCartAddItem
(
@CartID nvarchar(50),
@ProductID int,
@Quantity int
)
As
DECLARE @CountItems int
SELECT @CountItems = Count(ProductID)
FROM CMRC_ShoppingCart
WHERE ProductID = @ProductID AND CartID = @CartID
IF @CountItems > 0 /* 若購物車已經有此商品則更新數量 */
UPDATE CMRC_ShoppingCart
SET Quantity = (@Quantity + CMRC_ShoppingCart.Quantity)
WHERE ProductID = @ProductID AND CartID = @CartID
ELSE /* 若購物車尚無此商品則新增記錄 */
INSERT INTO CMRC_ShoppingCart(CartID, Quantity, ProductID)
VALUES(@CartID, @Quantity, @ProductID)
GO
購物車動作原理
購物車如下圖:
.gif)
購物車程式 ShoppingCart.aspx,包括 DataGrid 控制項:
<asp:DataGrid id="MyList" runat="server" Font-Names="Verdana" AutoGenerateColumns="False"
DataKeyField="Quantity" AlternatingItemStyle-CssClass="CartListItemAlt"
ItemStyle-CssClass="CartListItem" FooterStyle-CssClass="CartListFooter"
HeaderStyle-CssClass="CartListHead" ShowFooter="True" Font-Size="8pt"
Font-Name="Verdana" cellpadding="4" GridLines="Vertical" BorderColor="Black">
<AlternatingItemStyle CssClass="CartListItemAlt"></AlternatingItemStyle>
<ItemStyle CssClass="CartListItem"></ItemStyle>
<HeaderStyle CssClass="CartListHead"></HeaderStyle>
<FooterStyle CssClass="CartListFooter"></FooterStyle>
<Columns>
<asp:TemplateColumn HeaderText="產品編號">
<ItemTemplate>
<asp:Label id="ProductID" runat="server" Text='<%# DataBinder.Eval(Container.DataItem,
"ProductID") %>' />
</ItemTemplate>
</asp:TemplateColumn>
<asp:BoundColumn DataField="ModelName" HeaderText="產品名稱"></asp:BoundColumn>
<asp:BoundColumn DataField="ModelNumber" HeaderText="型號"></asp:BoundColumn>
<asp:TemplateColumn HeaderText="數量">
<ItemTemplate>
<asp:TextBox id="Quantity" runat="server" Columns="4" MaxLength="3"
Text='<%# DataBinder.Eval(Container.DataItem, "Quantity") %>' width="40px" />
</ItemTemplate>
</asp:TemplateColumn>
<asp:BoundColumn DataField="UnitCost" HeaderText="價格" DataFormatString="{0:c}">
</asp:BoundColumn>
<asp:BoundColumn DataField="ExtendedAmount" HeaderText="小計" DataFormatString="{0:c}">
</asp:BoundColumn>
<asp:TemplateColumn HeaderText="刪除">
<ItemTemplate>
<center>
<asp:CheckBox id="Remove" runat="server" />
</center>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>
當網頁載入時將執行 Page_Load(),從資料庫的取得購物車的資料後,再資料繫結 ProductID(商品編號)、ModelName(產品名稱)、ModelNumber(型號)、Quantity(數量)、UnitCost(價格) 欄位到 DataList 控制項,當呼叫 DataBind() 時執行 Web 使用者控制項的「<%# … %>」部份。
Page_Load() 中呼叫 PopulateShoppingCartList:
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles MyBase.Load
If Page.IsPostBack = False Then
'資料繫結購物車(Shopping Cart)以顯示
PopulateShoppingCartList()
End If
End Sub
其中 PopulateShoppingCartList 資料繫結購物明細到 DataGrid 購物車以更新顯示:
Sub PopulateShoppingCartList()
Dim cart As ASPNET.StarterKit.Commerce.ShoppingCartDB =
New ASPNET.StarterKit.Commerce.ShoppingCartDB()
'取得使用者的shopping cart ID
Dim cartId As String = cart.GetShoppingCartId()
'若購物車無項目則顯示訊息
If cart.GetItemCount(cartId) = 0 Then
DetailsPanel.Visible = False
MyError.Text = "目前在您的購物車中沒有任何項目。"
Else
'資料繫結shoppingcart購物明細
MyList.DataSource = cart.GetItems(cartId)
MyList.DataBind()
'更新總金額
lblTotal.Text = String.Format("{0:c}", cart.GetTotal(cartId))
End If
End Sub
其中 ShoppingCartDB.vb 的 GetItems() 執行預存程序 CMRC_ShoppingCartList,取得購物車資料庫的資料:
Public Function GetItems(ByVal cartID As String) As SqlDataReader
'由Web.Config取得資料庫連線字串, 設定預存程序名稱
Dim myConnection As SqlConnection =
New SqlConnection(ConfigurationSettings.AppSettings("ConnectionString"))
Dim myCommand As SqlCommand = New SqlCommand("CMRC_ShoppingCartList", myConnection)
'設定命令為預存程序
myCommand.CommandType = CommandType.StoredProcedure
'輸入預存程序輸入參數值
Dim parameterCartID As SqlParameter = New SqlParameter("@CartID", SqlDbType.NVarChar, 50)
parameterCartID.Value = cartID
myCommand.Parameters.Add(parameterCartID)
'連線資料庫並執行預存程序
myConnection.Open()
Dim result As SqlDataReader = myCommand.ExecuteReader(CommandBehavior.CloseConnection)
'傳回datareader結果
Return result
End Function
預存程序 CMRC_ShoppingCartList,從 CMRC_ShoppingCart 資料表中取得購物車記錄:
CREATE Procedure CMRC_ShoppingCartList
(
@CartID nvarchar(50)
)
AS
SELECT
CMRC_Products.ProductID, CMRC_Products.ModelName,
CMRC_Products.ModelNumber, CMRC_ShoppingCart.Quantity,
CMRC_Products.UnitCost,
Cast((CMRC_Products.UnitCost * CMRC_ShoppingCart.Quantity) as money) as ExtendedAmount
FROM CMRC_Products, CMRC_ShoppingCart
WHERE CMRC_Products.ProductID = CMRC_ShoppingCart.ProductID
AND CMRC_ShoppingCart.CartID = @CartID
ORDER BY CMRC_Products.ModelName, CMRC_Products.ModelNumber
GO
更新購物車動作原理
當更改購物車的商品數量或刪除後,按下 [Update Your Shopping Cart] 按鈕後將執行 UpdateShoppingCartDatabase():
'更新購物車(Shopping Cart)資料庫
Sub UpdateShoppingCartDatabase()
Dim cart As ASPNET.StarterKit.Commerce.ShoppingCartDB =
New ASPNET.StarterKit.Commerce.ShoppingCartDB()
'取得使用者的shopping cart ID
Dim cartId As String = cart.GetShoppingCartId()
'循環取得購物車商品明細
Dim i As Integer
For i = 0 To MyList.Items.Count - 1
'取得row's controls references
Dim quantityTxt As TextBox = CType(MyList.Items(i).FindControl("Quantity"), TextBox)
Dim remove As CheckBox = CType(MyList.Items(i).FindControl("Remove"), CheckBox)
Dim quantity As Integer
Try
quantity = CInt(quantityTxt.Text)
'若數量有變動, 或勾選刪除
If quantity CInt(MyList.DataKeys(i)) Or remove.Checked = True Then
Dim lblProductID As Label = CType(MyList.Items(i).FindControl("ProductID"), Label)
If quantity = 0 Or remove.Checked = True Then
'若數量為0, 或勾選刪除則移除此項目
cart.RemoveItem(cartId, CInt(lblProductID.Text))
Else
'更新項目
cart.UpdateItem(cartId, CInt(lblProductID.Text), quantity)
End If
End If
Catch
MyError.Text = "部份輸入有誤."
End Try
Next
End Sub
結帳動作原理
當結帳按下 [Final Check Out] 按鈕後將執行 CheckoutBtn_Click(),首先執行 UpdateShoppingCartDatabase 先更新購物車,再導向結帳 Checkout.aspx 程式:
Private Sub CheckoutBtn_Click(ByVal sender As Object,
ByVal e As System.Web.UI.ImageClickEventArgs) Handles CheckoutBtn.Click
'更新購物車(Shopping Cart)
UpdateShoppingCartDatabase()
Dim cart As ASPNET.StarterKit.Commerce.ShoppingCartDB =
New ASPNET.StarterKit.Commerce.ShoppingCartDB()
'計算shopping cart ID
Dim cartId As String = cart.GetShoppingCartId()
'若購物車不是空的, 則導向買單(checkout)網頁
If cart.GetItemCount(cartId) 0 Then
Response.Redirect("Checkout.aspx")
Else
MyError.Text = "購物車是空的, 不能買單."
End If
End Sub
結帳 Checkout.aspx 程式,包括 DataGrid 控制項:
<asp:DataGrid id="MyDataGrid" width="90%" BorderColor="Black" GridLines="Vertical"
cellpadding="4" Font-Name="Verdana" Font-Size="8pt" ShowFooter="True"
HeaderStyle-CssClass="CartListHead" FooterStyle-CssClass="cartlistfooter"
ItemStyle-CssClass="CartListItem" AlternatingItemStyle-CssClass="CartListItemAlt"
AutoGenerateColumns="False" runat="server" Font-Names="Verdana">
<AlternatingItemStyle CssClass="CartListItemAlt"></AlternatingItemStyle>
<ItemStyle CssClass="CartListItem"></ItemStyle>
<HeaderStyle CssClass="CartListHead"></HeaderStyle>
<FooterStyle CssClass="cartlistfooter"></FooterStyle>
<Columns>
<asp:BoundColumn DataField="ModelName" HeaderText="產品名稱"></asp:BoundColumn>
<asp:BoundColumn DataField="ModelNumber" HeaderText="型號號碼"></asp:BoundColumn>
<asp:BoundColumn DataField="Quantity" HeaderText="數量"></asp:BoundColumn>
<asp:BoundColumn DataField="UnitCost" HeaderText="價格" DataFormatString="{0:c}">
</asp:BoundColumn>
<asp:BoundColumn DataField="ExtendedAmount" HeaderText="小計" DataFormatString="{0:c}">
</asp:BoundColumn>
</Columns>
</asp:DataGrid>
當網頁載入時將執行 Page_Load(),ShoppingCartDB.vb 的 GetItems() 執行預存程序 CMRC_ShoppingCartList,取得購物車資料庫的資料從資料庫的取得購物車的資料後,再資料繫結 ModelName(產品名稱)、ModelNumber(型號)、Quantity(數量)、UnitCost(價格) 欄位到 DataList 控制項顯示結帳清單:
ByVal e As System.EventArgs) Handles MyBase.Load
If Page.IsPostBack = False Then
'取得shopping cart ID
Dim cart As ASPNET.StarterKit.Commerce.ShoppingCartDB =
New ASPNET.StarterKit.Commerce.ShoppingCartDB()
Dim cartId As String = cart.GetShoppingCartId()
'結帳商品列表
MyDataGrid.DataSource = cart.GetItems(cartId)
MyDataGrid.DataBind()
'更新總金額
TotalLbl.Text = String.Format("{0:c}", cart.GetTotal(cartId))
End If
End Sub
當結帳按下 [Submit] 按鈕後將執行 SubmitBtn_Click(),執行 PlaceOrder() 下訂單:
您的訂單代號(Order Number)為: </b>" & orderId
SubmitBtn.Visible = False
End If
End Sub
預存程序 CMRC_OrdersAdd,首先新增資料到訂單資料表 CMRC_Orders,接著複製購物車資料到訂單明細資料表 CMRC_OrderDetails,最後移除購物車資料:
Commerce Starter Kit 可以由其他應用程式透過Web Services送出訂單、查詢訂單。InstantOrder.asmx 程式負責這兩個動作。由其他應用程式透過 Web Services 查詢訂單的程式為 InstantOrder.asmx 中的 CheckStatus():
ShoppingCartDB.vb 的 AddItem(),新增項目到購物車。OrdersDB.vb的PlaceOrder(),下訂單。OrdersDB.vb 的GetOrderDetails(),從資料庫取得訂單的詳細資料傳回到 DataSet。