您的位置:首页 > 运维架构

.Net Pet Shop 4 初探之四:购物篮模块

2008-12-21 15:40 288 查看
前言
购物篮模块是PetShop4中最最重的模块之一。在数据库中,与购物篮联系最紧密的就是Cart表了(关于Cart表请参见本系列博文第一篇相关部分)。
购物篮的数据访问层(DAL)
购物篮模块中设计了实体类,这样可以快速为数据库中各字段赋值,体现数据结构的整体性。PetShop4的所有的实体类都保存的项目Model中。
其中的CardItemInfo类与Card表基本对应,可以实现对Card表的快速存取。
购物篮的数据访问是通过Profile工厂模式实现的。工厂模式的基本原理以前面的文章中已有简介,这里用户只要知道如何调用Profile就行了。最终实现对数据库的访问是通过SQLProfileDAL项目中的PetShopProfileProvider类来完成的。该类中有关购物篮的部分方法如下:
/// Retrieve collection of shopping cart items
public IList GetCartItems(string userName, string appName, bool isShoppingCart)
/// Update shopping cart for current user
public void SetCartItems(int uniqueID, ICollection cartItems, bool isShoppingCart)
/// Update activity dates for current user and application
public void UpdateActivityDates(string userName, bool activityOnly, string appName)
/// Retrive unique id for current user
public int GetUniqueID(string userName, bool isAuthenticated, bool ignoreAuthenticationType, string appName)
/// Create profile record for current user
public int CreateProfileForUser(string userName, bool isAuthenticated, string appName)
下图保存购物篮信息的实现流程图:



购物篮的业务逻辑层(BLL)
在三层结构中,业务逻辑层处在中间层,是承上启下的一层,它为用户调用提供一个接口,并启动数据访问层来完成用户操作,由于DAL与业务逻辑无关,所以BLL是实现用户数据逻辑处理的关键层.当数据访问层的SQL语句发生变化时,只需要改变DAL层的部分内容,不会影响到BLL等上面层.BLL主要作用就是实现当前业务的操作功能.
系统中所有业务逻辑层的处理类类位于BLL项目下,PepShop4中购物篮功能的业务逻辑主要包括:添加商品到购物篮,移除购物篮中的商品,更新购物篮中的某件商品的数量,清空购物篮,获取购物篮中商品总数及总价格,获得购物篮中某商品的记录等.实现这些操作主要是通过Card类来完成的,Card类的结构如下图:



购物篮的界面层(UI)
界面层位于Web项目下,购物篮的界面层文件是:ShoppingCard.aspx.打开该文件的HTML视图,
首先,该页面应用了母版面:MasterPageFile="~/MasterPage.master"
其次,页面上注册了一个用户控件:ShoppingCardControl,注册代码如下:
<%@ Register Src="Controls/ShoppingCartControl.ascx" TagName="ShoppingCartControl" TagPrefix="PetShopControl" %>
接下来在页面上声明了这一控件:

打开ShoppingCartControl.ascx控件的设计界面,购物篮商品列表是由一个Reparter控件来呈现的。其中记录显示格式如下:

                                                ' CommandName="Del" ImageUrl="~/Comm_Images/button-delete.gif"
                    OnCommand="CartItem_Command" ToolTip="Delete" />
                                                    '><%# string.Format("{0} {1}", Eval("Name"), Eval("Type")) %>
                                                    ' Width="20px">
                                <%# Eval("Price", "{0:c}")%>                   ' CommandName="Move" ImageUrl="~/Comm_Images/button-wishlist.gif" OnCommand="CartItem_Command" ToolTip="Move to wish list" />
                            显示购物篮界面
需要注意的是,当用户打开购物篮界面时,系统会自动检索用户之前添加过的购物篮信息,并加载到界面上。这一功能是怎样实现的呢?
加载先前购物信息的功能是在页面的“Page_PreRender”事件中完成的。该事件调用“BindCart”方法,其中“BindCart”方法的代码如下:
private void BindCart() { 
    ICollection cart = Profile.ShoppingCart.CartItems;
    if (cart.Count > 0) {
        repShoppingCart.DataSource = cart;
        repShoppingCart.DataBind();
        PrintTotal();
        plhTotal.Visible = true;
    }
    else {
        repShoppingCart.Visible = false;
        plhTotal.Visible = false;
        lblMsg.Text = "Your cart is empty.";
    }
}
添加商品到购物篮
protected void Page_PreInit(object sender, EventArgs e) {
    if (!IsPostBack) {
        string itemId = Request.QueryString["addItem"];
        if (!string.IsNullOrEmpty(itemId)) {
            Profile.ShoppingCart.Add(itemId);
            Profile.Save();
            // Redirect to prevent duplictations in the cart if user hits "Refresh"
            Response.Redirect("~/ShoppingCart.aspx", true);
        }
    }
}
其中语句:Profile.ShoppingCart.Add(itemId);是功能操作的关键语句,该语句的实现流程如下:
调用BLL项目中Cart类中的Add方法→调用Profile项目中PetShopProfileProvider类的SetPropertyValues方法
→调用同类中的SetCartItems方法向购物篮中添加商品信息
→调用SQLProfileDAL项目中的PetShopProfileProvider类的CreateProfileForUser方法添加用户的配置信息
更改商品数量
protected void BtnTotal_Click(object sender, System.Web.UI.ImageClickEventArgs e) {
    TextBox txtQuantity;
    ImageButton btnDelete;
    int qty = 0;
    foreach (RepeaterItem row in repShoppingCart.Items) {
        txtQuantity = (TextBox)row.FindControl("txtQuantity");
        btnDelete = (ImageButton)row.FindControl("btnDelete");
        if (int.TryParse(WebUtility.InputText(txtQuantity.Text, 10), out qty)) {                  
            if (qty > 0)
                Profile.ShoppingCart.SetQuantity(btnDelete.CommandArgument, qty);
            else if (qty == 0)
                Profile.ShoppingCart.Remove(btnDelete.CommandArgument);
        }
    }
    Profile.Save();
    BindCart();
}
计算商品总价
private void PrintTotal() {
    if (Profile.ShoppingCart.CartItems.Count > 0)
        ltlTotal.Text = Profile.ShoppingCart.Total.ToString("c");
}
移除购物篮中的商品
protected void CartItem_Command(object sender, CommandEventArgs e) {
    switch (e.CommandName.ToString()) {
        case "Del":
            Profile.ShoppingCart.Remove(e.CommandArgument.ToString());
            break;
        case "Move":
            Profile.ShoppingCart.Remove(e.CommandArgument.ToString());
            Profile.WishList.Add(e.CommandArgument.ToString());
            break;
    }
    Profile.Save();
    BindCart();
}
匿名用户到验证用户购物篮的转移
PetShop4中一个重要的特点是它允许用户不登录时就可以选择商品,并可以将商品添加到购物篮,然后当用户登录后,再将用户登录前选择的商品保存到验证过的个性配置中。
.Net 3.5提供了一种匿名登录的方法,它会为用户自动生成一个UserName,当匿名用户选择商品到购物篮中是地,系统自动在Profile表中保存这个匿名用户的名字,保存用户的购物篮,当用户登录后,只需要将表中的用户名替换掉就行了。
要实现此功能,首先,在Web.config中激活:

   
       
       
       
   
   
       
       
       
   

其次是要正确处理匿名迁移,系统中使用Profile_MigrateAnonymous事件来处理,此事件一般在Global.asax文件中。
void Profile_MigrateAnonymous(Object sender, ProfileMigrateEventArgs e) {
    ProfileCommon anonProfile = Profile.GetProfile(e.AnonymousID);
    // Merge anonymous shopping cart items to the authenticated shopping cart items
    foreach (CartItemInfo cartItem in anonProfile.ShoppingCart.CartItems)
        Profile.ShoppingCart.Add(cartItem);
    // Merge anonymous wishlist items to the authenticated wishlist items
    foreach (CartItemInfo cartItem in anonProfile.WishList.CartItems)
        Profile.WishList.Add(cartItem);
    // Clean up anonymous profile
    ProfileManager.DeleteProfile(e.AnonymousID);
    AnonymousIdentificationModule.ClearAnonymousIdentifier();
    // Save profile
    Profile.Save();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: