使用ASP.NET 2.0 Profile存儲用戶信息[翻譯]

作者: Stephen Walther
原文地址:http://msdn.microsoft.com/asp.net/default.aspx?pull=/library/en-us/dnvs05/html/UserProfiles.asp
譯 者:Tony Qu

概要:許多ASP.NET應用程序需要跨訪問的用戶屬性 跟蹤功能,在ASP.NET1.1中,我們只能人工實現這一功能。但如今,使用 ASP.NET 2.0的Profile對象,這個過程變得異 常簡單。Stephen Walther將驗證該對象,並向你展示如何使用Profile來跟蹤用戶屬性、創建一個購物籃,及其他一些例子。

總目錄
介紹
User Profile總攬
定義User Profile
使用Profile組
使用複雜的Profile屬性
繼承一個Profile
遷移匿名Profile設置
配置Profile Provider
管理Profiles並生成Profile報告
總結
相關書籍

Microsoft ASP.NET 2.0支持被稱爲Profile的新對象,它可以自動在多個Web應用程序的訪問之間存儲用戶信息。一個User Profile 中可以存儲各種類型的信息,這些信息既可以是簡單的string和integer類型,也可以是複雜的自定義類型。例如,你可以存儲用戶的姓、購物籃、用 戶屬性或網站使用情況統計。
本文中,你將學習如何在一個應用中定義user profile。我們也會向你演示如何配置使用不同 provider的profile。最後,你將學習如何管理和生成user profile的報告。

User Profiles總攬
Profile 對象與Session對象十分相似,但是更好用一些。與Session相似的地方在於,Profile是相對於一個特定的用戶的,也就是說,每 個Web應用程序的用戶都有他們自己的profile對象。與Session不同的是,Profile對象是持久對象。如果你向 Session中添加一個項,在你離開網站時,該項就會消失。而Profile則完全不同,當你修改Profile的狀態時,修改在 多個訪問之間均有效。

profile使用provider模式來存儲信息,默認情況下,user profile 的內容會保存在SQL Server Express數據庫中,該數據庫位於網站的App_Data目錄。然而,在本文的後半部分,你將瞭解如 何使用其他數據提供者(data provider)來存儲信息,如完整版的SQL Server中的一個數據庫或者一個Oracle數據庫。

與Session不同,Profile是強類型的,Session對象僅僅是一個項集合而已,而profile對象則有強類 型屬性。
使用強類型是有它的道理的。例如,使用強類型,你就可以在Microsoft Visual Web Developer中使用智能感知技術,當你鍵入Profile和一個點的時候,智能感知會彈出你已經定義過的profile屬性列 表。

 

定義user profile
你既可以在machine.config中,也可以在web.config中定義一個user profile, 由於你不能在應用程序的二級目錄中創建一個包含文件profile節的web.config文件,這意味着你將無法在一個應用程序中定義兩個以 上的profile。
在列表1的web.config中,列舉了一個簡單的profile定義的實例,該profile 有三個屬性,FirstName, LastName和PageVisits。

列表1
< configuration >
 
< system .web >
   
< authentication  mode ="Forms"   />
      
           
< anonymousIdentification  enabled ="true"   />
        
   
< profile >
               
< properties >
                  
< add 
        
name ="FirstName"   
        defaultValue
="??"
        allowAnonymous
="true"   />
      
< add 
        
name ="LastName"  
        defaultValue
="??"
        allowAnonymous
="true"   />
      
< add 
        
name ="PageVisits"
        type
="Int32"  
        allowAnonymous
="true" />
               
</ properties >
           
</ profile >
 
</ system.web >
</ configuration >


    由於該profile需要同時被匿名用戶和已認證用戶使用,因此我們在 web.config文件中增加包含一個 < anonymousIdentification>元素,有了這個元素,系統就會自動爲匿名用戶生成唯一的ID。仔細看的話我們會發現,每一個 pro

file屬性都有一個allowAnonymous特性,該特性表明這個profile屬性是否允許被匿名用戶使用。

 

    默認的profile屬性類型是System.String類型。列表1中,由於沒有爲FirstName 和LastName這兩個profile屬性增加type特性,那麼系統默認它們是string類型,而PageVisits屬性則指定了 type特性爲Int32,因此該profile屬性可用於表示一個整型值。

    最後,注意FirstName和LastName屬性都有defaultValue特性。你可以爲簡單的數據類型設置defaultValue特性,但你 不能爲複雜類型設置defaultValue特性。
 
    當你定義好一個profile之後,系統會自動在下一次頁面被調 用時,生成一個與該profile相對應的類。這個類會被保存在"Temporary ASP.NET Files Directory"目錄(該目錄也用於存放用於動態生成頁面的類)。你可以使用HttpContext的Profile屬性 (Property)調用該類。
    當你定義好一個profile後,你可以使用如下方法爲profile屬性賦值。

[Visual Basic .NET]
Profile.FirstName 
=   " Bill "

[C#]
Profile.FirstName 
=   " Bill " ;

 

任何在web.config中定義的profile 屬性都會在Profile對象中呈現。
列表2演示了你該如何使用profile來持久化保存用戶信息。這個頁顯示了 FirstName,LastName, PageVisits三個屬性的值,同時它包含了一個能夠用於修改這三個屬性的表單(form)。在Page_Load中更新PageVisits的值, 這意味着每一次刷新頁面,PageVisits的值都會改變。

使用ASP.NET 2.0  Pro<wbr>file存儲用戶信息(下)[翻譯] - °嶶涼°昜祥。ノ - °昜 祥°loneliness°

圖1 使用簡單的profile

列表 2. Simple.aspx (Visual Basic .NET)
< %@ Page Language = " VB "  % >
< script runat = " server " >

    
Sub  Page_Load()
        Profile.PageVisits 
+=   1
    
End Sub
    
    
Sub  UpdateProfile( ByVal  s  As   Object ByVal  e  As  EventArgs)
        Profile.FirstName 
=  txtFirstName.Text
        Profile.LastName 
=  txtLastName.Text
    
End Sub
    
</ script >

< html >
< head >
    
< title > Simple </ title >
</ head >
< body >
    
< form id = " form1 "  runat = " server " >
    
< b > Name: </ b >   < % =  Profile.FirstName % >   < % =  Profile.LastName % >
    
< br  />
    
< b > Page Visits: </ b >   < % =  Profile.PageVisits % >
    
    
< hr  />
    
    
< b > First Name: </ b >
    
< asp:TextBox ID = " txtFirstName "  Runat = " Server "   />
    
< br  />
    
< b > Last Name: </ b >
    
< asp:TextBox ID = " txtLastName "  Runat = " Server "   />
    
< br  />
    
< asp:Button 
        Text
= " Update Profile "  
        OnClick
= " UpdateProfile "  
        Runat
= " server "   />

    
</ form >
</ body >
</ html >

 

 

列表 2. Simple.aspx (C#)
<% @ Page Language = " C# "   %>
< script runat = " server " >

    
void  Page_Load() {
        Profile.PageVisits 
++ ;
    }
    
    
void  UpdateProfile(Object s, EventArgs e) {
        Profile.FirstName 
=  txtFirstName.Text;
        Profile.LastName 
=  txtLastName.Text;
    }
    
</ script >

< html >
< head >
    
< title > Simple </ title >
</ head >
< body >
    
< form id = " form1 "  runat = " server " >
    
< b > Name: </ b >   <%=  Profile.FirstName  %>   <%=  Profile.LastName  %>
    
< br  />
    
< b > Page Visits: </ b >   <%=  Profile.PageVisits  %>
    
    
< hr  />
    
    
< b > First Name: </ b >
    
< asp:TextBox ID = " txtFirstName "  Runat = " Server "   />
    
< br  />
    
< b > Last Name: </ b >
    
< asp:TextBox ID = " txtLastName "  Runat = " Server "   />
    
< br  />
    
< asp:Button ID = " Button1 "  
        Text
= " Update Profile "  
        OnClick
= " UpdateProfile "  
        Runat
= " server "   />

    
</ form >
</ body >
</ html >

 

如果你多次訪問列表2中的頁面,你會注意到PageVisits在不斷增大。如果你關閉的瀏覽器,並 在一週之後調用該頁面,PageVisits屬性仍然會保留原值。從這一點可以看出Profile爲每個用戶自動保存一個副本。

使用Profile組

儘管你僅可以爲一個應用程序定義一個 profile ,但如果你需要讓幾個 profile 屬性一起工作,把它們放在組中,會讓你覺得它們更易管理。

例如,在列表 3 中,有一個帶有兩個組的 profile ,這兩個組分別是 Address Preferences

列表3. Web.Config
< configuration >
< system .web >
      
   
< anonymousIdentification  enabled ="true"   />
        
   
< profile >
               
< properties >
   
< group  name ="Address" >
                  
< add 
         
name ="Street"   
         allowAnonymous
="true"   />
                 
< add 
         
name ="City"   
         allowAnonymous
="true"   />
   
</ group >
   
< group  name ="Preferences" >
      
< add 
         
name ="ReceiveNewsletter"  
         type
="Boolean"
         defaultValue
="false"
         allowAnonymous
="true"   />
   
</ group >
              
</ properties >
        
</ profile >
</ system.web >
</ configuration >

當你用組來定義 profile 時,你應該使用組名來設置或讀取 profile 屬性。例如,在列表 3 中,你可以使用以下一些句子來完成三個 profile 屬性的賦值。

[Visual Basic .NET]

Profile.Address.City 
=   " Modesto "
Profile.Address.Street 
=   " 111 King Arthur Ln "
Profile.Preferences.ReceiveNewsletter 
=  False

[C#]

Profile.Address.City 
=   " Modesto " ;
Profile.Address.Street 
=   " 111 King Arthur Ln " ;
Profile.Preferences.ReceiveNewsletter 
=   false ;

一個 profile 的定義只能包含一 層組,換句話說,你不能把其他的組放在一個 profile 組的下面一層。

使用複雜的profile屬 性

到目前爲止,我們已經介紹了聲明包含簡單類型(如string或整型)屬性的profile,其實你也可以在profile 中聲明覆雜屬性。
舉個例子,假設你現在需要在profile中存儲一個購物籃,如果這樣做的話,你就可以在每次訪問網站時獲得自己的購 物籃。
列表4 聲明瞭一個包含profile,這個profile包含一個名爲ShoppingCart的屬性,而該屬性的 type特性是一個叫ShoppingCart的類(我們接下來會創建該類),該類名是有效的。
我們還會注意到,該聲明中包含一個 serializeAs特性,該特性可以幫助ShoppingCart使用二進制序列化器(binary serializer)進行持久化,而不是使用xml序列化器。

 

列表4 Web.config

<
configuration >
< system .web >

  
< anonymousIdentification  enabled ="true"   />
  
  
< profile >
    
< properties >
    
< add 
       
name ="ShoppingCart"
       type
="ShoppingCart"
       serializeAs
="Binary"
       allowAnonymous
="true"   />
    
</ properties >
  
</ profile >
</ system.web >
</ configuration >

列表5 中有一個簡單購物籃的實現代碼,該購物籃擁有添加和刪除項(item)的方法(method),同時它還擁有兩個屬性(property),一個是用於獲 得該購物籃中的所有項的,一個是用於表示所有商品的總價的。

 

 

列表5 ShoppingCart (Visual Basic.NET)

Imports
 Microsoft.VisualBasic

< Serializable() >  _
Public   Class  ShoppingCart
    
Public  _CartItems  As   New  Hashtable()

    
'  Return all the items from the Shopping Cart
     Public   ReadOnly   Property  CartItems()  As  ICollection
        
Get
            
Return  _CartItems.Values
        
End   Get
    
End Property

    
'  The sum total of the prices
     Public   ReadOnly   Property  Total()  As   Decimal
        
Get
            
Dim  sum  As   Decimal
            
For   Each  item  As  CartItem  In  _CartItems.Values
                sum 
+=  item.Price  *  item.Quantity
            
Next
            
Return  sum
        
End   Get
    
End Property

    
'  Add a new item to the shopping cart
     Public   Sub  AddItem( ByVal  ID  As   Integer , _
      
ByVal  Name  As   String ByVal  Price  As   Decimal )
        
Dim  item  As  CartItem  =   CType (_CartItems(ID), CartItem)
        
If  item  Is   Nothing   Then
            _CartItems.Add(ID, 
New  CartItem(ID, Name, Price))
        
Else
            item.Quantity 
+=   1
            _CartItems(ID) 
=  item
        
End   If
    
End Sub

    
'  Remove an item from the shopping cart
     Public   Sub  RemoveItem( ByVal  ID  As   Integer )
        
Dim  item  As  CartItem  =   CType (_CartItems(ID), CartItem)
        
If  item  Is   Nothing   Then
            
Return
        
End   If
        item.Quantity 
-=   1
        
If  item.Quantity  =   0   Then
            _CartItems.Remove(ID)
        
Else
            _CartItems(ID) 
=  item
        
End   If
    
End Sub

End Class

< Serializable() >  _
Public   Class  CartItem

    
Private  _ID  As   Integer
    
Private  _Name  As   String
    
Private  _Price  As   Decimal
    
Private  _Quantity  As   Integer   =   1

    
Public   ReadOnly   Property  ID()  As   Integer
        
Get
            
Return  _ID
        
End   Get
    
End Property

    
Public   ReadOnly   Property  Name()  As   String
        
Get
            
Return  _Name
        
End   Get
    
End Property

    
Public   ReadOnly   Property  Price()  As   Decimal
        
Get
            
Return  _Price
        
End   Get
    
End Property

    
Public   Property  Quantity()  As   Integer
        
Get
            
Return  _Quantity
        
End   Get
        
Set ( ByVal  value  As   Integer )
            _Quantity 
=  value
        
End   Set
    
End Property

    
Public   Sub   New ( ByVal  ID  As   Integer , _
      
ByVal  Name  As   String ByVal  Price  As   Decimal )
        _ID 
=  ID
        _Name 
=  Name
        _Price 
=  Price
    
End Sub
End Class

 

 

列表5 ShoppingCart (c#)

using
 System;
using  System.Collections;

[Serializable]
public   class  ShoppingCart
{
    
public  Hashtable _CartItems  =   new  Hashtable();

    
//  Return all the items from the Shopping Cart
     public  ICollection CartItems
    {
        
get  {  return  _CartItems.Values; }
    }

    
//  The sum total of the prices
     public   decimal  Total
    {
        
get  
        {
            
decimal  sum  =   0 ;
            
foreach  (CartItem item  in  _CartItems.Values)
                sum 
+=  item.Price  *  item.Quantity;
            
return  sum;
        }
    }

    
//  Add a new item to the shopping cart
     public   void  AddItem( int  ID,  string  Name,  decimal  Price)
    {
        CartItem item 
=  (CartItem)_CartItems[ID];
        
if  (item  ==   null )
            _CartItems.Add(ID, 
new  CartItem(ID, Name, Price));
        
else
        {
            item.Quantity
++ ;
            _CartItems[ID] 
=  item;
        }
    }

    
//  Remove an item from the shopping cart
     public   void  RemoveItem( int  ID)
    {
        CartItem item 
=  (CartItem)_CartItems[ID];
        
if  (item  ==   null )
            
return ;
        item.Quantity
-- ;
        
if  (item.Quantity  ==   0 )
            _CartItems.Remove(ID);
        
else
            _CartItems[ID] 
=  item;
    }

}

[Serializable]
public   class  CartItem
{
    
private   int  _ID;
    
private   string  _Name;
    
private   decimal  _Price;
    
private   int  _Quantity  =   1 ;

    
public   int  ID
    {
        
get  {  return  _ID; }
    }

    
public   string  Name
    {
        
get  {  return  _Name; }
    }

    
public   decimal  Price
    {
        
get  {  return  _Price; }
    }

    
public   int  Quantity
    {
        
get  {  return  _Quantity; }
        
set  { _Quantity  =  value; }
    }

    
public  CartItem( int  ID,  string  Name,  decimal  Price)
    {
        _ID 
=  ID;
        _Name 
=  Name;
        _Price 
=  Price;
    }
}

如 果你把列表5中的代碼添加到應用程序的App_Code目錄中,購物籃會自動被編譯。

 

在列表5中有一點值得 注意,那就是ShoppingCart和CartItem類都加上了可序列化的特性,這一點對於他們能否被序列化十分重要,只有這樣才能保存在Profile 對象中。

最後,列表6的頁面顯示了可以被添加到購物籃中的產品。購物籃是通過BindShoppingCart方法從Profile 對象中載入,該方法把購物籃中的對象綁定到一個GridView對象上,這些對象可以通過ShoppingCart類的CartItems屬性獲得。

使用ASP.NET 2.0 Pro<wbr>file存儲用戶信息(下)[翻譯] -  °嶶涼°昜祥。ノ - °昜 祥°loneliness°
圖 2 在profile中存儲購物籃

AddCartItem方法用於在購物籃中添加一個產品,該方法中包含了檢測Profile 是否存在ShoppingCart的代碼。對於Profile中存儲的對象,你必須自己實例化這些對象,他們不會自動實例化。

RemoveCartItem方法用於從購物籃中移除一個產品,該方法只是簡單地通過調用Profile中的ShoppingCart 對象的RemoveItem方法。

 

列表 6 - Products.aspx (Visual Basic .NET)

<
%@ Page Language = " VB "  % >

< script runat = " server " >

    
Sub  Page_Load()
        
If   Not  IsPostBack  Then
            BindShoppingCart()
        
End   If
    
End Sub
        
    
Sub  BindShoppingCart()
        
If   Not  Profile.ShoppingCart  Is   Nothing   Then
            CartGrid.DataSource 
=  Profile.ShoppingCart.CartItems
            CartGrid.DataBind()
            lblTotal.Text 
=  Profile.ShoppingCart.Total.ToString( " c " )
        
End   If
    
End Sub
   
    
Sub  AddCartItem( ByVal  s  As   Object ByVal  e  As  EventArgs)
        
Dim  row  As  GridViewRow  =  ProductGrid.SelectedRow

        
Dim  ID  As   Integer   =   CInt (ProductGrid.SelectedDataKey.Value)
        
Dim  Name  As   String   =  row.Cells( 1 ).Text
        
Dim  Price  As   Decimal   =   CDec (row.Cells( 2 ).Text)
        
        
If  Profile.ShoppingCart  Is   Nothing   Then
            Profile.ShoppingCart 
=   New  ShoppingCart
        
End   If
        Profile.ShoppingCart.AddItem(ID, Name, Price)
        BindShoppingCart()
    
End Sub
    
    
Sub  RemoveCartItem( ByVal  s  As   Object ByVal  e  As  EventArgs)
        
Dim  ID  As   Integer   =   CInt (CartGrid.SelectedDataKey.Value)
        Profile.ShoppingCart.RemoveItem(ID)
        BindShoppingCart()
    
End Sub
</ script >

< html >
< head >
    
< title > Products </ title >
</ head >
< body >
    
< form id = " form1 "  runat = " server " >

    
< table width = " 100% " >
    
< tr >
        
< td valign = " top " >
    
< h2 > Products </ h2 >     
    
< asp:GridView
        ID
= " ProductGrid "
        DataSourceID
= " ProductSource "
        DataKeyNames
= " ProductID "
        AutoGenerateColumns
= " false "
        OnSelectedIndexChanged
= " AddCartItem "
        ShowHeader
= " false "
        CellPadding
= " 5 "
        Runat
= " Server " >
        
< Columns >
            
< asp:ButtonField 
                CommandName
= " select "
                Text
= " Buy "   />
            
< asp:BoundField
                DataField
= " ProductName "   />
            
< asp:BoundField
                DataField
= " UnitPrice "  
                DataFormatString
= " {0:c} "   />
        
</ Columns >
    
</ asp:GridView >



        
    
< asp:SqlDataSource
        ID
= " ProductSource "
        ConnectionString
=
" Server=localhost;Database=Northwind;Trusted_Connection=true; "
        SelectCommand
=  
          
" SELECT ProductID,ProductName,UnitPrice FROM Products "
        Runat
= " Server "   />
        
</ td >
        
< td valign = " top " >
        
< h2 > Shopping Cart </ h2 >
        
< asp:GridView
            ID
= " CartGrid "
            AutoGenerateColumns
= " false "
            DataKeyNames
= " ID "
            OnSelectedIndexChanged
= " RemoveCartItem "
            CellPadding
= " 5 "  
            Width
= " 300 "
            Runat
= " Server " >
            
< Columns >
            
< asp:ButtonField
                CommandName
= " select "
                Text
= " Remove "   />
            
< asp:BoundField
                DataField
= " Name "  
                HeaderText
= " Name "   />
            
< asp:BoundField
                DataField
= " Price "  
                HeaderText
= " Price "  
                DataFormatString
= " {0:c} "   />
            
< asp:BoundField
                DataField
= " Quantity "  
                HeaderText
= " Quantity "   />
            
</ Columns >
        
</ asp:GridView >
        
< b > Total: </ b >  
        
< asp:Label ID = " lblTotal "  Runat = " Server "   />
        
</ td >
     
</ tr >
     
</ table >
    
</ form >
</ body >
</ html >

 

 

列 表 6. Products.aspx (C#)

<%
@ Page Language = " C# "   %>
<% @ Import Namespace = " System.Globalization "   %>
< script runat = " server " >

    
void  Page_Load() {
        
if  ( ! IsPostBack)
            BindShoppingCart();
    }
        
    
void  BindShoppingCart() 
    {
        
if  (Profile.ShoppingCart  !=   null
        {
            CartGrid.DataSource 
=  Profile.ShoppingCart.CartItems;
            CartGrid.DataBind();
            lblTotal.Text 
=  Profile.ShoppingCart.Total.ToString( " c " );
        }
    }
   
    
void  AddCartItem(Object s, EventArgs e) 
    {
        GridViewRow row 
=  ProductGrid.SelectedRow;

        
int  ID  =  ( int )ProductGrid.SelectedDataKey.Value;
        String Name 
=  row.Cells[ 1 ].Text;
        
decimal  Price  =  Decimal.Parse(row.Cells[ 2 ].Text, 
          NumberStyles.Currency);
        
        
if  (Profile.ShoppingCart  ==   null )
            Profile.ShoppingCart 
=   new  ShoppingCart();
       
        Profile.ShoppingCart.AddItem(ID, Name, Price);
        BindShoppingCart();
    }
    
    
void  RemoveCartItem(Object s, EventArgs e) 
    {
        
int  ID  =  ( int )CartGrid.SelectedDataKey.Value;
        Profile.ShoppingCart.RemoveItem(ID);
        BindShoppingCart();
    }
</ script >

< html >
< head >
    
< title > Products </ title >
</ head >
< body >
    
< form id = " form1 "  runat = " server " >

    
< table width = " 100% " >
    
< tr >
        
< td valign = " top " >
    
< h2 > Products </ h2 >     
    
< asp:GridView
        ID
= " ProductGrid "
        DataSourceID
= " ProductSource "
        DataKeyNames
= " ProductID "
        AutoGenerateColumns
= " false "
        OnSelectedIndexChanged
= " AddCartItem "
        ShowHeader
= " false "
        CellPadding
= " 5 "
        Runat
= " Server " >
        
< Columns >
            
< asp:ButtonField 
                CommandName
= " select "
                Text
= " Buy "   />
            
< asp:BoundField
                DataField
= " ProductName "   />
            
< asp:BoundField
                DataField
= " UnitPrice "  
                DataFormatString
= " {0:c} "   />
        
</ Columns >
    
</ asp:GridView >



        
    
< asp:SqlDataSource
        ID
= " ProductSource "
        ConnectionString
=
" Server=localhost;Database=Northwind;Trusted_Connection=true; "
        SelectCommand
=
          
" SELECT ProductID,ProductName,UnitPrice FROM Products "
        Runat
= " Server "   />
        
</ td >
        
< td valign = " top " >
        
< h2 > Shopping Cart </ h2 >
        
< asp:GridView
            ID
= " CartGrid "
            AutoGenerateColumns
= " false "
            DataKeyNames
= " ID "
            OnSelectedIndexChanged
= " RemoveCartItem "
            CellPadding
= " 5 "  
            Width
= " 300 "
            Runat
= " Server " >
            
< Columns >
            
< asp:ButtonField
                CommandName
= " select "
                Text
= " Remove "   />
            
< asp:BoundField
                DataField
= " Name "  
                HeaderText
= " Name "   />
            
< asp:BoundField
                DataField
= " Price "  
                HeaderText
= " Price "  
                DataFormatString
= " {0:c} "   />
            
< asp:BoundField
                DataField
= " Quantity "  
                HeaderText
= " Quantity "   />
            
</ Columns >
        
</ asp:GridView >
        
< b > Total: </ b >  
        
< asp:Label ID = " lblTotal "  Runat = " Server "   />
        
</ td >
     
</ tr >
     
</ table >
    
</ form >
</ body >
</ html >

繼承一個profile
你也 可以通過從一個已經存在的profile類中繼承一個profile來完成對profile的定義,這種特性能夠幫助你在 多個應用程序中使用相同的profile。
例如,列表7中列出了一個擁有多個用戶屬性的類,該類是從ProfileBase類繼承而來 的(你可以在System.Web.Profile中找到)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章