ASP.NET用户个性化设置Profile——配置2

 前面一篇文章讲到了如何快速的配置起Profile和如何在应用程序中使用Profile存储用户自定义信息。 但是在前面,Profile中存储的是简单数据类型,比如int、String等。现在,我们讲解如何存储自定义数据类型,比如:购物车类。在这里就把Petshop中的这一块单独抠出来,稍许简化一点,做一个讲解。

  首先打开上一章的网站(或者新建一个网站,按照前几篇文章讲解的内容配置好Membership、profile、连接字符串等),然后在统一解决方案下再添加一个类库项目,起名为Models。在里边添加一个类CartItemInfo。内容如下:

 

  public   class  CartItemInfo
    {
        
public   string  Name {  get set ; }
        
public   string  Type {  get set ; }
        
public   decimal  Price {  get set ; }
        
public   int  Quantity {  get set ; }
    }

 

  代表购物车中存储的一项商品。

  第三步:再次添加一个类库项目,起名为BLL。然后添加Models层的引用。然后在其中添加一个类Cart代表购物车:

 

ExpandedBlockStart.gif 代码
     public   class  Cart
    {
        
private  Dictionary < string , CartItemInfo >  cartItems  =   new  Dictionary < string , CartItemInfo > ();

        
///   <summary>
        
///  总价
        
///   </summary>
         public   decimal  Total
        {
            
get
            {
                
decimal  total  =   0 ;
                
foreach  (CartItemInfo item  in  cartItems.Values)
                {
                    total 
+=  item.Price  *  item.Quantity;
                }
                
return  total;
            }
        }
        
///   <summary>
        
///  设置某一项产品的数量
        
///   </summary>
        
///   <param name="Name"></param>
        
///   <param name="qty"></param>
         public   void  SetQuantity( string  Name,  int  qty)
        {
            cartItems[Name].Quantity 
=  qty;
        }
        
///   <summary>
        
///  购物车中,产品个数
        
///   </summary>
         public   int  Count
        {
            
get
            {
                
return  cartItems.Count;
            }
        }

        
public   void  Add( string  name,  string  type,  decimal  price,  int  quantity)
        {
            CartItemInfo item;
            
// 判断该产品是否在集合当中,如果有,则直接数量+1
            
// 如果没有,则创建一个新的购物车项加入到集合当中
             if  ( ! cartItems.TryGetValue(name,  out  item))
            {
                item 
=   new  CartItemInfo { Name  =  name, Type  =  type, Price  =  price, Quantity  =  quantity };
                cartItems.Add(item.Name, item);
            }
            
else
            {
                cartItems[name].Quantity
+=quantity ;
            }
        }
        
public   void  Add(CartItemInfo item)
        {
            Add(item.Name, item.Type, item.Price, item.Quantity);
        }
        
///   <summary>
        
///  从购物车中移除一项
        
///   </summary>
        
///   <param name="name"></param>
         public   void  Remove( string  name)
        {
            cartItems.Remove(name);
        }
        
///   <summary>
        
///  清空购物车
        
///   </summary>
         public   void  Clear()
        {
            cartItems.Clear();
        }
        
///   <summary>
        
///  得到购物车列表
        
///   </summary>
         public  ICollection < CartItemInfo >  CartItems
        {
            
get
            {
                
return  cartItems.Values;
            }
        }
    }

 

  第四步:在网站项目中添加BLL层和Models层的引用。

  ok到此所有准备工作告一段落,开始配置Profile。打开网站的web.config文件,修改Profile节点的Properties节点为下面内容:

 

< properties >
    
< add  name ="Cart"  type ="BLL.Cart"  allowAnonymous ="true" />
</ properties >

 

  注意:type必须前面带上命名空间的名字。

  配置完毕!

  现在新建一个页面,页面很简单:

 

< form  id ="form1"  runat ="server" >
    
< div >
    名称:
< asp:TextBox  runat ="server"  ID ="txtName" ></ asp:TextBox >< br  />
    类型:
< asp:TextBox  runat ="server"  ID ="txtType" ></ asp:TextBox >< br  />
    价格:
< asp:TextBox  runat ="server"  ID ="txtPrice" ></ asp:TextBox >< br  />
    数量:
< asp:TextBox  runat ="server"  ID ="txtQuantity" ></ asp:TextBox >< br  />
    
< asp:Button  runat ="server"  Text ="添加到购物车"  ID ="btnAddCart"  OnClick ="btnAddCart_Click"   />
    
</ div >
</ form >

 

  后台代码为:

 

     public   void  btnAddCart_Click( object  sender, EventArgs e)
    {
        CartItemInfo item 
=   new  CartItemInfo
        {
            Name 
=  txtName.Text,
            Type 
=  txtType.Text,
            Price 
=   decimal .Parse(txtPrice.Text),
            Quantity 
=   int .Parse(txtQuantity.Text)
        };

        Profile.Cart.Add(item);
    }

 

  首先在Profile.Cart.Add(item);这里加一个断点,然后以调试方式运行页面。在四个文本框中分别输入内容,并单击添加到购物车,第一次命中断点时,可以从监视窗口中看到Profile.Cart.CartItems.Count=1,说明刚才创建的对象添加到了集合当中。可是当我们再次点击添加到购物车按钮时,情况发生了变化在运行Profile.Cart.Add(item);这句代码之前Profile.Cart.CartItems.Count属性=0!刚才添加的哪个商品哪去了?为什么之前的简单数据类型数据可以保留,而现在变为购物车类之后却又不可以了呢?

 

  要解决这个问题有两种做法:

  第一种,修改Properties节点如下所示:

 

< properties >
    
< add  name ="Cart"  type ="BLL.Cart"  allowAnonymous ="true"  serializeAs ="Binary" />
</ properties >

 

  给Cart增加了一个属性serializeAs="Binary",然后给Models层的CartItemInfo类和BLL层的Cart类,增加一个[Serializable]特性:

 

    [Serializable]
    
public   class  Cart{....}


    [Serializable]
    
public   class  CartItemInfo{.....}

 

  然后再次重复刚才的步骤,你会发现:数据可以正确保存了。

 

  第二种方法:需要修改一下代码了:将Cart类的Dictionary<string,CartItemInfo>替换为List<CartItemInfo>,并且将所有需要保存的成员设置为Public访问权限,即可。

 

  为什么要做这两种修改之后,才可以正确保存用户的数据呢?这是因为,Profile在保存用户自定义类型时,需要将产生的对象“序列化”后,保存到数据库当中。在需要读取数据时,将保存的数据“反序列化”后,还原成对象。前面的两种改变,其实就是序列化的两种方式:二进制序列化和XML序列化。当然,在存储简单数据类型时,Profile会将这些内容序列化为字符串。

  所谓序列化,就是将一个内存中的对象,转变成一个磁盘文件的过程。顾名思义,二进制序列化就是转变成一个二进制文件,XML序列化转变成一个XML文件。举个例子,我们玩的游戏。最著名的就是大菠萝《暗黑破坏神2》了,我们经常会去网上下载一些非常牛X的存档,然后放到游戏目录下,就可以去游戏中体验这些非常牛的角色和装备。那么这些存档,其实就是序列化之后的文件。游戏将这些磁盘上的文件反序列化后变成内存当中的对象,也就是人物了。XML序列化的好处在于你可以将对象中的数据传送给其他应用程序。

 

  总结一下:当我们需要在Profile中存放自定义数据类型时,需要指明自定义对象的序列化方式(默认为XML序列化方式)。

   XML序列化需要将自定义类型的数据成员设为公有,私有成员和方法不会被保存。同时XML序列化方式支持实现了ICollection接口的集合(前面将Dictionary换成List,是因为Dictionary没有实现ICollection接口,它实现的是IDictionary接口)。下图是XML序列化后,数据库中保存的数据:

  

      二进制序列化同样非常简单,对于要序列化的对象没有任何要求,只要在需要序列化的类上面增加[Serilizable]特性即可。需要注意的是,类中的所有成员都必须有此特性。这种特性不能继承,也就是说父类加了,子类还得加。

 

       好了,关于Profile就先说到这里,后面还有两个点:匿名用户向登录用户的数据迁移,和自定义数据存储

Example download: /Files/jhxk/Profile/ProfileCartDemo.rar

 

转载于:https://www.cnblogs.com/jhxk/articles/1900451.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值