HomeASP.NET Order-Related Modules for an ASP.NET AJAX ...
Order-Related Modules for an ASP.NET AJAX Server-Centric Based Online Shopping Website
Welcome to the fifth part of an eleven-part series that focuses on helping you build your own online shopping web site. Things up to now have become more and more interesting because we are about to delve into the following modules: viewing products, going shopping, placing orders, and so forth. Let’s discuss them one by one.
Contributed by Xianzhong Zhu Rating: / 7 December 26, 2007
Viewing products is mainly accomplished through the "Product.aspx" page. Let's first take a quick look at the most complicated page (in fact the main page). The following Figure 15 shows one of the run-time snapshots when no users have been registered.
Figure 15-one of the run-time snapshots for the "Product.aspx" page
On the whole, this page is a typical four-part user interface design mainly based on HTML <table> elements. The topmost part is the ugly logo by me. The left part (which is composed of several user controls, and because no users have been registered, parts of other sub panels do not appear) acts as the control panel to schedule each component of the whole shopping city. The right and larger part consists of two parts. The upper part is a product category list (DataList), and the lower part shows the corresponding products that belong to the selected product category (GridView). The bottom part of this page is a simple footnote just to simulate a typical website layout.
First, the above code only relates to the GridView control that is used to display the corresponding product information that belongs to the selected product category. To gain a partially refreshing effect, we typically use an ASP.NET AJAX server control named UpdatePanelto enclose the GridView control.
Second, we've leveraged one of the important triggers, AsyncPostBackTrigger,to invoke the updating action of the UpdatePanelcontrol. The following shows the related code:
private void BindProductData(int nCategoryID){
///define the class that gets the data
Product product = new Product();
SqlDataReader dr = product.GetProductByCategory(nCategoryID);
Here we have already provided detailed comments. As you see, the general routine of the code is like those arranged in the previous modules. Here, the "ProductView" control corresponds to the ASP.NET GridView to display the selected goods, while the "ProductList" refers to the ASP.NET control named DataList to show the product category.
For now, acute readers may have already detected a secret. Here, again, we list the related code:
How can we display the images within the database? As the previous sections mentioned, we use a field of the "image" type to directly store the binary image data into the table. In earlier ASP.NET solutions, it is very difficult to show an image at the specified position on a web page, especially as the image data is persisted into the database table. Another commonly-used way to deal with image data is to independently store the image files while only their related paths are in the table. Each solution has its own pros and cons.
Here, we adopt the new ASP.NET 2.0 project-the newly-introduced web handler ".ashx" file. According to MSDN, the web handler ".ashx" file works just like an aspx file except WE are one step away from the messy browser level where HTML and C# mix. One reason we would write an .ashx file instead of an .aspx file is that our output is not going to a browser but to an XML-consuming client of some kind. As you have seen, the key piece lies in 'ImageUrl='<%# Eval("PictureID", "../Handler.ashx?Id={0}") %>''. And the following corresponds to the final form of it detected in the browser side.
In the above code, the core component is the public method, namelyProcessRequest. When the parameterized URL is passed to it, it accepts the parameter to a variable named "photoId," as follows.
Next, in the helper function GetPhoto, I directly use SQL operations to fetch the image data from the database (of course you can move the module elsewhere if you prefer). The subsequent lines of code in the ProcessRequest methodabstracts the binary image data and then writes it to the specified context, as follows:
After clicking the "Add to shopping cart" button, the related item can be put into the shopping cart, all of which is finished within the ProductView_RowCommand click event handler. In conclusion, the function will accomplish the following tasks:
If there are no products inside the shopping cart, create an instance of the OrderInfo(i.e. order) class which is used to save the cart related info;
Obtain information about the product and create an instance of the OrderItemInfo(i.e. item) class to save this product-related info;
Add the item objectinto the OrderItemList listof the order object;
Update the info of the cart;
If there are already products inside the shopping cart, get the order object used to save the cart-related info from the Session system variable;
Obtain info of the product and create an instance of the OrderItemInfo(i.e. item) class to save this product-related info;
Search from inside the order objectsub items that contain the same product as that inside the item project, and update the sub items info;
Update the shopping cart.
The following lists the complete code for the ProductView_RowCommand function:
"alert('You have succeeded in adding the selected goods into the shopping cart!');", true);
}
For brevity, we omit the code listing for the GetOrderItemInformation helper function.
In addition, there are several issues that deserve to be discussed. First, because when we get the product information, the row index of the ProductView controlhas to be used, at the earlier event (RowCreated) of the ProductView controlwe put the index number of the product into the CommandArgument propertyof the buyBtn button(which is the IDproperty of the "Add to shopping cart" button). Here's the related code:
Second, in traditional ASP.NET applications most of us like to use 'Response.Write("<script>window.alert('....')</script>");' to tell users the result of the current operation. However, due to leveraging the ASP.NET AJAX server control named UpdatePanelto enclose the GridView control we can not use that any more, or else we will meet some error like the one displayed in Figure 16.
Figure 16-an error occurs when we use 'Response.Write(...);' inside UpdatePanel control to give some clue to the users
Therefore, we have to resort to a static function named RegisterStartupScriptof the ScriptManager control. Here is an example of what happens when the "adding" operation is successful.
This is a must have for the customers that have already logged into the system. When they click the "My Shopping Cart" hyperlink on the left of the "product.aspx" page they will be redirected to another page, "cart.aspx" whose snapshot is shown in the following Figure 17.
Figure 17-the design-time snapshot for viewing the shopping cart
Here, you can click the "Product Name" related hyperlink to view the detailed information about the selected goods or delete it by click the "X" symbol (a hyperlink) at the rightmost of the row. Since this is a simple ASP.NET page we won't discuss it any more. But there is a flaw that needs to be pulled: here although in the "cart.aspx" page the customer can change the count of the specified article, but when he is navigated to another page, "order.aspx." to finally place the order, he still cannot change the number of that article. So, sorry for my not having provided this support; you have to click "Add to the shopping cart" button ntimes if you want to buy nproducts of the related one.
Committing the order
As hinted above, when the user clicks the button labeled "Submit this shopping and create the order" on the "cart.aspx" page he will be navigated to the "order.aspx" page to finally commit the order. Now let's first take a look at one of the run-time snapshot as illustrated in Figure 18.
Figure 18-the run-time snapshot for submitting the final order
As seen from the figure, the GridView control at the top gives detailed info about each item for purchase. Neighboring it there is a line further totaling all the info above it. The large part at the middle of the page display is the contact information of the current customer. Clicking the "Previous" button will lead the user back to the "View shopping cart" page, while clicking the "Confirm the shopping info and commit the order" button means the user has confirmed all the above info and decided to submit the order to the seller.
At the start of the initialization of the "order.aspx," related data are bound to the ProductView control, i.e. displaying the products within the cart, then continue to show the detailed info about the user and the order. The following code corresponds to the initializing process.
Notwithstanding the fact that it is pretty long, the inner logic is rather easy. The key sentence is 'SqlDataReader recr = user.GetSingleUser(nUserID);' while the key variable still lies in Session. OK, by calling the two helper functions, namedShowCartInfoand BindUserData, all the required info is displayed on the screen.
Submitting the Order
The following shows the click event handler for the "Confirm the shopping info and commit the order" in the above Figure 18.
Response.Write("<script>alert("You have succeeded in committing the order!")</script>");
}
Here, we first obtain the order info out of the Session variable, then submit it to the remote SQL Server database, and at last create an order. That's it.
Author's Note: First, because this is just a demonstration application, we have not attached all the order-related info to the popular online payment systems, such as PayPal or any other famous system. Thus, in practical development, you will have to do this by yourself. Second, to grasp all the data relations introduced in the above several modules you should carefully study the relationships between some classes such as OrderForm, OrderInfo, and OrderItemInfo.