ASP.NET 2.0个性化配置(profile)
強類型 長期保存? 支持匿名用戶
定義配置(profile)
<?xml?version="1.0"?>
<configuration?xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
????<appSettings/>
????<connectionStrings>
????????<add?name="Northwind"?connectionString="Server=localhost;Integrated?Security=True;Database=Northwind"?providerName="System.Data.SqlClient"/>
????</connectionStrings>
????<system.web>
????????<anonymousIdentification?enabled="true"?/>
????????<profile>?? //定義配置(profile)
????????????<properties>
????????????????<add?name="Theme"?allowAnonymous="true"?/>
????????????????<add?name="LastVisit"?type="System.DateTime"?allowAnonymous="true"?/>
????????????</properties>
????????</profile>
<!--
????????<webParts>? //定義配置(webParts)
????????????<personalization?defaultProvider="AspNetSqlPersonalizationProvider"/>
????????</webParts>
-->
????????<!--?
????????????Set?compilation?debug="true"?to?insert?debugging?symbols?into?the?compiled?page.
????????????Because?this?affects?performance,?set?this?value?to?true?only?during?development.
????????-->
????????<compilation?debug="true">
????????????<expressionBuilders>
????????????????<add?expressionPrefix="Version"?type="VersionExpressionBuilder"/>
????????????</expressionBuilders>
????????</compilation>
????????<!--
????????????The?<authentication>?section?enables?configuration?of?the?security?authentication
????????????mode?used?by?ASP.NET?to?identify?an?incoming?user.?
????????-->
????????<authentication?mode="Windows"/>
????????<!--
????????????The?<customErrors>?section?enables?configuration?of?what?to?do?if/when?an?unhandled
????????????error?occurs?during?the?execution?of?a?request.??Specifically,?it?enables?developers
????????????to?configure?html?error?pages?to?be?displayed?in?place?of?a?error?stack?trace.
????????-->
????????<customErrors?mode="RemoteOnly"?defaultRedirect="GenericErrorPage.htm">
????????????<!--?
????????????<error?statusCode="403"?redirect="NoAccess.htm"/>
????????????<error?statusCode="404"?redirect="FileNotFound.htm"/>
????????-->
????????</customErrors>
????</system.web>
</configuration>
使用配置(profile)
//increment the current user's post cout
profile.posts = profile.posts+1;
// update the current user's last post date
profile.lastpost = datetime.now;
個性化數據將存入數據庫
介紹
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。
<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。仔細看的話我們會發現,每一個 profile屬性都有一個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屬性賦值。
Profile.FirstName?=?"Bill"
[C#]
Profile.FirstName?=?"Bill";
任何在web.config中定義的profile屬性都會在Profile對象中呈現。
列表2演示了你該如何使用profile來持久化保存用戶信息。這個頁顯示了FirstName,LastName, PageVisits三個屬性的值,同時它包含了一個能夠用于修改這三個屬性的表單(form)。在Page_Load中更新PageVisits的值,這意味著每一次刷新頁面,PageVisits的值都會改變。
圖1 使用簡單的profile
列表 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屬性的賦值。
[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序列化器。
<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 (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對象中。
圖2 在profile中存儲購物籃
AddCartItem方法用于在購物籃中添加一個產品,該方法中包含了檢測Profile是否存在ShoppingCart的代碼。對于Profile中存儲的對象,你必須自己實例化這些對象,他們不會自動實例化。
RemoveCartItem方法用于從購物籃中移除一個產品,該方法只是簡單地通過調用Profile中的ShoppingCart對象的RemoveItem方法。
<%@?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中找到)
在列表8中的Web.config包含一個從UserInfo類繼承而來的profile,通過該聲明,新的profile可以獲得UserInfo類的所有屬性。
列表 7. UserInfo (C#) using System;
using System.Web.Profile;
public class UserInfo : ProfileBase
{
private string _FirstName;
private string _LastName;
public string FirstName
{
get { return _FirstName; }
set { _FirstName = value; }
}
public string LastName
{
get { return _LastName; }
set { _LastName = value; }
}
}
using?System;
using?System.Web.Profile;
public?class?UserInfo?:?ProfileBase
{
????private?string?_FirstName;
????private?string?_LastName;
????public?string?FirstName?
????{
????????get?{?return?_FirstName;?}
????????set?{?_FirstName?=?value;?}
????}
????public?string?LastName
????{
????????get?{?return?_LastName;?}
????????set?{?_LastName?=?value;?}
????}
}
列表 8. Web.Config
<configuration>
????<system.web>
???????????<anonymousIdentification?enabled="true"?/>
???<profile?inherits="UserInfo"?/>
????</system.web>
</configuration>
遷移匿名Profile設置
Profile對象既可用于匿名用戶也可以用于已認證用戶。然而,當用戶從匿名用戶狀態轉換為已認證用戶狀態時,Profile對象能夠以一種令人難以理解的方式完成任務。
當匿名用戶使用Profile對象時,用戶profile是與一個隨機生成的號碼相關聯的,該號碼是根據每個用戶唯一生成的,它保存在瀏覽器的cookie中,無論何時該用戶返回應用程序,該用戶的Profile設置會被自動加載。
如果匿名用戶通過認證的話,所有與該用戶相關的profile就會丟失,同時系統會生成一個新的profile。這時該Profile信息將與用戶名相關聯,而非唯一識別號。
要想理解所有這些工作,最好的方法就是看看下面的例子。列表9中的web.config定義了一個profile,該profile只有一個FavoriteColor屬性。
列表 9 Web.config
<configuration>
<system.web>
???<authentication?mode="Forms"?/>
??????
???????????<anonymousIdentification?enabled="true"?/>
????????
???<profile>
???<properties>
??????????????????<add?
?????????name="FavoriteColor"
?????????allowAnonymous="true"?
?????????defaultValue="Red"?/>
???????????????</properties>
???????????</profile>
</system.web>
</configuration>
列表10中有一個包含兩個按鈕的頁面,分別是login和logout按鈕,其中還有一個用于更新FavoriteColor屬性的表單。
列表10. Anonymous.aspx (C#)
<%@?Page?Language="C#"?%>
<script?runat="server">
????void?Login(Object?s,?EventArgs?e)
????{
????????FormsAuthentication.SetAuthCookie("Bill",?false);
????????Response.Redirect(Request.Path);
????}
????void?Logout(Object?s,?EventArgs?e)
????{
????????FormsAuthentication.SignOut();
????????Response.Redirect(Request.Path);
????}
????void?UpdateProfile(Object?s,?EventArgs?e)
????{
????????Profile.FavoriteColor?=?txtFavoriteColor.Text;
????}
????
????void?Page_PreRender()
????{
????????lblUsername.Text?=?Profile.UserName;
????????lblFavoriteColor.Text?=?Profile.FavoriteColor;
????}
????????
</script>
<html>
<head>
????<title>Anonymous</title>
</head>
<body>
????<form?id="form1"?runat="server">
????<asp:Button
????????Text="Login"
????????OnClick="Login"
????????Runat="Server"?/>
????<asp:Button?ID="Button1"
????????Text="Logout"
????????OnClick="Logout"
????????Runat="Server"?/>
????<hr?/>
????<asp:TextBox????
????????id="txtFavoriteColor"
????????Runat="Server"?/>
????<asp:Button
????????Text="Update?Profile"
????????OnClick="UpdateProfile"
????????Runat="Server"?/>
????<hr?/>
????<b>Username:</b>
????<asp:Label??
????????id="lblUsername"
????????Runat="Server"?/>
????<br?/>
????<b>Favorite?Color:</b>
????<asp:Label
????????id="lblFavoriteColor"
????????Runat="Server"?/>????
????????
????</form>
</body>
</html>
當你打開第一個頁面時,UserName的值是一個隨機生成的唯一識別號(見圖3)。當你按下Login按鈕后,你就完成了身份認證,它是通過用戶票據(User Bill)完成的。
圖3 使用匿名和認證profile
列表10的頁面中包含一個用于更新FavoriteColor的表單,要注意的是,在你登錄登出的時候,會分別生成兩個不同的profile。例如當你先登錄,后登出的話,那么系統會生成一個隨機的唯一識別號。
在很多情況下,你需要把匿名profile遷移到認證profile狀態,如果你需要遷移profile屬性值的話,你可以利用 ProfileModule類的MigrateAnonymous事件完成該任務,該事件只能在Global.asax文件中進行處理。列表11中的 Global.asax演示了你如何才能實現FavoriteColor屬性的遷移。
列表?11.?Global.asax?(C#)
<%@?Application?Language="C#"?%>
<script?runat="server">
????void?Profile_MigrateAnonymous(Object?s,?
??????ProfileMigrateEventArgs?e)
????{
????????ProfileCommon?anonProfile?=?
??????????Profile.GetProfile(e.AnonymousId);
????????Profile.FavoriteColor?=?anonProfile.FavoriteColor;
????}???
</script>
通過Profile類的GetProfile()方法你可以獲得匿名profile,該方法接收一個唯一識別號,并且返回與唯一識別號對應的profile。ProfileMigrateEventArgs對象包含一個匿名識別號。
配置Profile Provider
默認情況下,profile被保存在sqlserver 2005 express數據庫,它位于App_Data目錄中,這或許在你開發一些普通的asp.net應用程序時是沒有問題的,但很有可能,你需要把你的應用程序的profile保存在另一個數據庫中,比如一個完整版的SqlServer 2005的實例中,而該數據庫又位于你局域網的某個位置。
Profile使用Provider模式,通過修改web.config或machine.config的設置來告訴系統把信息存儲在哪里。
ASP.NET本身配了一個profile provider,叫SqlProfileProvider。如果你感到困惑,你可以通過繼承ProfileProvider基類來創建一個自己的 provider。例如,你可以創建一個基于Oracle數據庫或MySql數據庫的Provider。在這里,我們將只討論最簡單的方法,即通過SqlServer數據庫來保存profile信息。
要使用Microsoft SQL Server存儲profile信息,必須完成兩個步驟。首先,你必須安裝SQL Server數據庫,然后你必須重新設置配置文件。
ASP.NET 2.0框架提供了一個用于配置SQL Server來存儲Profile信息的工具,該工具叫做aspnet_regsql,它位于Windows\Microsoft.NET\ Framework\[.NET版本號]。執行該工具后,你會看到圖4中的ASP.NET SQL Server安裝向導。
圖4 使用ASP.NET SQL Server安裝程序
SQL Server安裝向導會指導你完成必要的步驟,完成這些步驟后,向導會自動創建用于存儲profile信息的存儲過程和表結構。
在你完成SQL Server數據庫的配置后,你需要修改web.config或machine.config中的數據庫連接設置來指向服務器上的SQL Server數據庫,本例中該數據庫的實例名為MyServer,列表12列出了該配置文件。
列表 12.?Web.Config
<configuration>
<connectionStrings>
<add
name="myConnectionString"
connectionString=
"Server=MyServer;Trusted_Connection=true;database=MyDatabase"?/>
</connectionStrings>
<system.web>
<anonymousIdentification?enabled="true"?/>
<profile?defaultProvider="MyProfileProvider">
<providers>
<add
name="MyProfileProvider"
type="System.Web.Profile.SqlProfileProvider"
connectionStringName="myConnectionString"?/>
</providers>
<properties>
<add
name="FirstName"
allowAnonymous="true"?/>
<add
name="LastName"
allowAnonymous="true"?/>
</properties>
</profile>
</system.web>
</configuration>
在列表12中的profile配置中,包含了一個defaultProvider特性,這個特性指向一個叫MyProfileProvider的 profile provider,而這個provider定義是在profile標記的<providers>節中完成的。 MyProfileProvider則使用一個叫MyConnectionString的連接字符串完成數據庫連接,并保存profile信息到數據庫中。MyConnectionString可以在位于web.config開頭的<connectionStrings>節中找到。
管理profile并生成profile報告
Profile會對象自動保存用戶profile信息,這既是好事業是壞事。說它是好事,是因為你不需要寫存儲信息的所有邏輯代碼,說它是壞事,是因為這樣可能造成一大堆無用的信息被保存在數據庫中。
幸運的是,ASP.NET 2.0框架包含一個叫做ProfileManager的類,你可以使用它來管理profile信息。它包含了相當多的方法使你能夠有效地管理profile并且生成profile報表,下面列出了一些該類的重要方法:
- DeleteInactiveProfiles. 刪除一個特定日期之前的所有profile
- DeleteProfile. 刪除特定用戶的profile
- DeleteProfiles. 刪除一個profile集合
- FindInactiveProfilesByUserName. 返回一個ProfileInfo對象的集合,該集合表示的profile是匹配一個某個名字,并且是從某個特定日期開始一直未被使用
- FindProfilesByUserName. 返回一個ProfileInfo對象集合,該集合與某個用戶名相關聯
- GetAllInactiveProfiles. 返回一個ProfileInfo對象集合,該集合表示的profile是從某個特定日期開始一直未被使用的profile
- GetAllProfiles. 返回一個ProfileInfo對象集合,該集合表示所有的profile
- GetNumberOfInactiveProfiles. 返回從某個特定日期開始一直未被使用的profile的數量
- GetNumberOfProfiles. 返回profile總數
- IsAnonymous. 表示該profile是否為匿名profile
- LastActivityDate. 最后一次profile被訪問的時間和日期
- LastUpdatedDate. 最后一次profile被升級的時間和日期
- Size. 表示profile的大小,這是在profile provider存儲profile信息時記錄的
- UserName. 與profile關聯的用戶名
ProfileManager既可以在asp.net頁面下使用,也可以在其它程序中使用。例如,你可能需要做一個控制臺程序用于每天清除長時間未使用的 profile。列表14的控制臺程序會刪除七天未使用的profile,你可以使用Windows計劃任務(Windows Scheduled Tasks)來安排該程序的執行時間。
列表?14.?DeleteInactiveProfiles?(C#)
using?System;
using?System.Web.Profile;
public?class?DeleteInactiveProfiles
{????
????public?static?void?Main()
????{
??????int?deleted?=?0;
??????deleted?=?
????????ProfileManager.DeleteInactiveProfiles(
????????ProfileAuthenticationOption.All,?
????????DateTime.Now.AddDays(-7));
??????Console.WriteLine("Deleted?"?+?
????????deleted.ToString()?+?"?profiles"?);
????}??????
}
你可以通過一下的命令行指令對列表14進行編譯
[Visual?Basic?.NET]
C:\WINDOWS\Microsoft.NET\Framework\v2.0.40607\vbc?
??/r:System.Web.dll?DeleteInactiveProfiles.vb
[C#]
C:\WINDOWS\Microsoft.NET\Framework\v2.0.40607\csc?
??DeleteInactiveProfiles.cs
你還可以使用ProfileManager類生成profile信息報表。例如,如果你打算生成一個用戶調查的報表,你可以把用戶調查保存在profile中,這樣就可以輕易的使用ProfileManager生成你需要的報表。
列表15中的web.config中有三個屬性:SurveyCompleted、FavoriteLanguage 和 FavoriteEnvironment
Listing?15.?Web.Config
<configuration?xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
????
???<system.web>
??????
??????????????<anonymousIdentification?enabled="true"?/>
??????<profile>
??????<properties>
??????????????????????<add?
????????????name="SurveyCompleted"
????????????type="Boolean"
????????????allowAnonymous="true"?/>
??????????????????????<add?
????????????name="FavoriteLanguage"
????????????allowAnonymous="true"?/>
?????????????????????<add?
????????????name="FavoriteEnvironment"
????????????allowAnonymous="true"?/>
??????</properties>
??????????????</profile>
?</system.web>
</configuration>
列表16中的頁面演示了一個簡單的用戶調查。該頁面包含兩個Panel控件,第一個控件中有兩個調查問題,當用戶完成調查后,第一個控件會自動隱藏,而第二個會顯示出來,第二個Panel有一段表示感謝的文字。
列表 16. Survey.aspx?(C#)
<%@?Page?Language="C#"?%>
<script?runat="server">
????void?SaveSurvey(Object?s,?EventArgs?e)
????{????
????????Profile.FavoriteLanguage?=?rdlLanguage.SelectedItem.Text;
????????Profile.FavoriteEnvironment?=?rdlEnvironment.SelectedItem.Text;
????????Profile.SurveyCompleted?=?true;
????}
????
????void?Page_PreRender()
????{????
????????if?(Profile.SurveyCompleted)?
????????{
????????????pnlSurvey.Visible?=?false;
????????????pnlSurveyCompleted.Visible?=?true;
????????}
????????else
????????{
????????????pnlSurvey.Visible?=?true;
????????????pnlSurveyCompleted.Visible?=?false;
????????}
????}
????
</script>
<html>
<head>
????<title>Survey</title>
</head>
<body>
????<form?id="form1"?runat="server">
????
????<asp:Panel?ID="pnlSurvey"?Runat="Server">
????What?is?your?favorite?programming?language?
????<br?/>
????<asp:RadioButtonList?
????????id="rdlLanguage"
????????runat="Server">
????????<asp:ListItem?Text="VB.NET"?Selected="True"?/>????
????????<asp:ListItem?Text="C#"?/>
????????<asp:ListItem?Text="J#"?/>????
????</asp:RadioButtonList>
????<p> </p>
????What?is?your?favorite?development?environment?
????<br?/>
????<asp:RadioButtonList?
????????id="rdlEnvironment"
????????runat="Server">
????????<asp:ListItem?Text="VS.NET"?Selected="True"?/>????
????????<asp:ListItem?Text="Web?Matrix"?/>
????????<asp:ListItem?Text="Notepad"?/>????
????</asp:RadioButtonList>
????<p> </p>????
????<asp:Button?ID="Button1"
????????Text="Submit?Survey"
????????Onclick="SaveSurvey"
????????Runat="Server"?/>
????</asp:Panel>
????<asp:Panel?ID="pnlSurveyCompleted"?Runat="Server">
????Thank?you?for?completing?the?survey!
????</asp:Panel>
????</form>
</body>
</html>
列表17中顯示調查的結果,該頁面中有一個顯示ProfileInfo對象集合的GridView控件,該ProfileInfo對象集合是由 ProfileManager的GetAllProfiles方法獲得的。當你點擊GridView中的任意一行的Select鏈接時,你將會看到對這個問題的調查結果,該調查結果是由Profile類的GetProfile方法獲得的。
圖5 顯示調查結果
列表 17.?SurveyResults.aspx?(C#)
<%@?Page?Language="C#"?%>
<script?runat="server">
????void?Page_Load()
????{????
????????ResultsGrid.DataSource?=?
ProfileManager.GetAllProfiles(ProfileAuthenticationOption.All);
????????ResultsGrid.DataBind();
????}
????
????void?DisplayProfileDetails(Object?s,?EventArgs?e)
????{
????????ProfileCommon?SelectedProfile?=?
????????????Profile.GetProfile(ResultsGrid.SelectedValue.ToString());
????????lblLanguage.Text?=?SelectedProfile.FavoriteLanguage;
????????lblEnvironment.Text?=?SelectedProfile.FavoriteEnvironment;
????}
????
</script>
<html>
<head>
????<title>Survey?Results</title>
</head>
<body>
????<form?id="form1"?runat="server">
????<h2>Survey?Results</h2>
????<asp:GridView?
????????id="ResultsGrid"
????????DataKeyNames="UserName"
????????AutoGenerateSelectButton="true"
????????OnSelectedIndexChanged="DisplayProfileDetails"
????????SelectedRowStyle-BackColor="LightYellow"
????????Runat="Server"?/>
????<p> </p>
????<h2>Survey?Details</h2>
????<b>Favorite?Language:</b>
????<asp:Label??
????????id="lblLanguage"
????????Runat="Server"?/>
????<br?/>
????<b>Favorite?Environment:</b>
????<asp:Label??
????????id="lblEnvironment"
????????Runat="Server"?/>
????</form>
</body>
</html>
轉載于:https://www.cnblogs.com/ghd258/archive/2005/10/20/258434.html
總結
以上是生活随笔為你收集整理的ASP.NET 2.0个性化配置(profile)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 三十条生意经
- 下一篇: sp_decrypt