ASP.NET专题研究——角色和Profile
(一)用戶(hù)角色的問(wèn)題:
??????????? 匿名用戶(hù)和非匿名用戶(hù)雖然可以在一定程度上避免訪(fǎng)問(wèn)人數(shù)太多帶來(lái)的管理紊亂和安全性問(wèn)題,但是僅有這項(xiàng)是遠(yuǎn)遠(yuǎn)不夠的。為了職責(zé)明確,避免不必要的糾葛和扯皮的事情發(fā)生,在后臺(tái)網(wǎng)站管理上通常我們會(huì)給不同登錄的人員分配不同的任務(wù),賦予它們?cè)L問(wèn)不同頁(yè)面的權(quán)限。我們通常把這種稱(chēng)之為“用戶(hù)角色”(Role)。
??????????? 在ASP.NET中啟用用戶(hù)角色非常簡(jiǎn)單——只需解決方案管理器右上角的一個(gè)(榔頭+地球)的圖標(biāo),進(jìn)入頁(yè)面之后點(diǎn)擊“Enabled Role”,然后添加一些角色名稱(chēng)(隨便,比如admin,guest,user等)。啟用Role在web.config對(duì)應(yīng)的代碼也是異常簡(jiǎn)單:
<roleManager enabled="true" cacheRolesInCookie="true">
</roleManager>
??????????? 如果你要對(duì)某個(gè)頁(yè)面(或者某個(gè)路徑下所有頁(yè)面)權(quán)限限制,只要這樣做:
<location path="Default2.aspx">
??? <system.web>
????? <authorization>
??????? <allow roles=”admin”/>
??????? <deny roles=”*” />
????? </authorization>
??? </system.web>
?</location>
這樣一來(lái),不是admin權(quán)限的人就不能訪(fǎng)問(wèn)這個(gè)頁(yè)面了(會(huì)出錯(cuò)的,說(shuō)頁(yè)面找不到)。不過(guò)這一個(gè)頁(yè)面太“土”,您完全可以配置自己的頁(yè)面,在web.config中這樣配置:
<customErrors mode="RemoteOnly" >
<error statusCode="403" redirect="NoAccess.htm" />
</ customErrors>
?
(二)Profile(個(gè)性文件)配置:
??????????? 如果你上百度、Google等一些大型網(wǎng)站,您會(huì)發(fā)現(xiàn)即便你沒(méi)有登錄,你照樣也可以對(duì)某些頁(yè)面進(jìn)行設(shè)置(比如調(diào)整背景色、大小等)。稍后你關(guān)閉頁(yè)面,隔一段時(shí)間之后打開(kāi)仍然是你原先設(shè)置的樣子,這個(gè)效果通常被我們成為個(gè)性配置(Profile)。
??????????? 以往在傳統(tǒng)WinForm程序中,保留這種個(gè)性配置可以通過(guò)讀寫(xiě)xml文件和(反)序列化以達(dá)到目的。但是Web程序是無(wú)狀態(tài)連接,同時(shí)其機(jī)制也迫使其不可能像WinForm程序一樣可以把所有配置一股腦兒地往客戶(hù)端那兒拋,然后由服務(wù)器讀取。在最初的一段日子里,我們經(jīng)常用Session存儲(chǔ)每一個(gè)私有用戶(hù)的信息,但是Session一旦用戶(hù)中斷連接(無(wú)論正常與否)結(jié)果Session的東西全部被丟棄了。如果放到Cookie里呢,Cookie只能存儲(chǔ)字符串,不能存儲(chǔ)大量對(duì)象的東西。所以我們急迫需要一種新技術(shù)——該技術(shù)既可以以對(duì)象的模式記錄每一個(gè)用戶(hù)的內(nèi)容,同時(shí)還要保證客戶(hù)端即便中斷也不丟失信息。這種技術(shù)在ASP.NET2.0中已經(jīng)被實(shí)現(xiàn),成為Profile。
??????????? 比如一個(gè)用戶(hù)訪(fǎng)問(wèn)百度的頁(yè)面(假設(shè)是ASP.NET開(kāi)發(fā)該頁(yè)面),那么我們要記住他曾經(jīng)第一次設(shè)置的背景色,以便下次訪(fǎng)問(wèn)仍舊記住該背景色(個(gè)性化)。我們可以按照以下步驟在前幾章的基礎(chǔ)上進(jìn)行配置:
1、配置Profile(web.config):
<anonymousIdentification enabled="true"/>
<profile automaticSaveEnabled="true">
????? <properties>
?????? ???? ?<add allowAnonymous="true" defaultValue="White" />
????? </properties>
</profile>
這里注意幾點(diǎn):
?????????????? “anonymousIdentification”:表示啟用匿名機(jī)制。
?????????????? “automaticSaveEnabled”:表示當(dāng)使用Profile的地方頁(yè)面(被)提交的時(shí)候,自動(dòng)寫(xiě)入數(shù)據(jù)庫(kù)對(duì)應(yīng)的profile中所有東西(如果是false,您必須使用Profile.Save()強(qiáng)行寫(xiě)入數(shù)據(jù)庫(kù))。
?????????????? “allowAnonymous”:表示當(dāng)前的這個(gè)可被記錄的屬性是否支持匿名。
?
2、現(xiàn)在我們?cè)俅位氐角懊婺莻€(gè)“個(gè)性化設(shè)置背景色”問(wèn)題——假設(shè)你的頁(yè)面是這樣設(shè)計(jì)的(加粗體字是因?yàn)樵瓉?lái)生成的頁(yè)面代碼中不包含此類(lèi)相關(guān)信息,為了便于后臺(tái)控制):
<body id="mybody" runat="server">
……
??????????? 先請(qǐng)您在Page_Load中代碼這樣寫(xiě):
protected void Page_Load(object sender, EventArgs e)
??? {
??????? mybody.Style[HtmlTextWriterStyle.BackgroundColor] = Profile.BackColor;???? //動(dòng)態(tài)設(shè)置BackColor的內(nèi)容,注意到Profile.的時(shí)候,智能感知出來(lái)BackColor的提示了嗎?可見(jiàn)Profile是強(qiáng)類(lèi)型的。
??? }
隨后放上一個(gè)按鈕,然后在按鈕中簡(jiǎn)單寫(xiě)這樣的代碼:
protected void Button1_Click(object sender, EventArgs e)
{
??????????? Profile.BackColor = “Blue”;
}
點(diǎn)擊按鈕,然后關(guān)閉瀏覽器,然后打開(kāi)頁(yè)面,是不是背景色發(fā)生變化了?很有意思吧?
(三)Profile多類(lèi)型嵌套:
??????????? 有時(shí)為了比較系統(tǒng)化、正規(guī)化描述一個(gè)人的特征(比如身高、年齡。性別等)。我們往往可以這樣做:
<profile automaticSaveEnabled="true">
????? <properties>
??????? ??? <group>
???????? ?????????????? ?<add/>
????????? ????????????? <add/>
????????? ????????????? <add/>
?????? ???? ?</group>
????? </properties>
??? </profile>
然后我可以這樣調(diào)用代碼:Profile.Person.Sex/Age/name….
Group標(biāo)簽就是用于嵌套屬性的,原則上可以嵌套N個(gè)屬性,而且可以為每個(gè)屬性指定是否匿名等特性。同時(shí),大家應(yīng)該注意到一個(gè)問(wèn)題,Age和Sex的類(lèi)型不應(yīng)該是String的(因?yàn)槟J(rèn)是String)類(lèi)型,所以我在此地強(qiáng)制指定了它們的類(lèi)型。現(xiàn)在帶來(lái)一個(gè)新問(wèn)題——如果某個(gè)Profile的屬性是自定義類(lèi)型呢?
(四)Profile的自定義類(lèi)型:
??????????? 在Profile中,自定義變得非常直觀(guān)而且簡(jiǎn)單:
<profile automaticSaveEnabled="true">
????? <properties>
????????? ? <add type='InfoList' serializeAs='Binary'/>
????? </properties>
</profile>
注意:type這里的完整寫(xiě)法是“命名空間.類(lèi)名”,但是由于InfoList沒(méi)有命名空間(直接在App_Code文件夾下),所以允許這樣寫(xiě);同時(shí)必須把這個(gè)類(lèi)表示成[Serializable],以便序列化后寫(xiě)入數(shù)據(jù)庫(kù)(Binary的形式)。
(五)匿名用戶(hù)和登錄用戶(hù)的Profile:
??????????? 現(xiàn)在無(wú)論是淘寶、網(wǎng)易,還是百度的商品拍賣(mài)網(wǎng)站上都有“購(gòu)物車(chē)”,其大致可以允許你暫時(shí)在未登錄的情況下先選擇物品添加進(jìn)入購(gòu)物車(chē),然后結(jié)賬的時(shí)候登錄,成功以后把所有匿名選擇的物品轉(zhuǎn)移到已登陸的那個(gè)帳號(hào)。這功能很容易實(shí)現(xiàn)嗎?我們先看一個(gè)小例子(方便起見(jiàn),這里只在Person下弄一個(gè)Cart的字符串?dāng)?shù)組):
protected void Page_Load(object sender, EventArgs e)
??? {
??????? if (!IsPostBack)
??????? {
??????????? ProfileManager.DeleteInactiveProfiles(ProfileAuthenticationOption.All, DateTime.Now);
??????????? Profile.Person.Cart = "蘋(píng)果";
??????????? Profile.Save();
??????????? Response.Write("用戶(hù)名?:" + Profile.UserName);
??????????? Response.Write("購(gòu)物情況?:" + Profile.Person.Cart);
??????? }
??????
??? }
protected void Button1_Click(object sender, EventArgs e)
??? {
??????? FormsAuthentication.SetAuthCookie("abd", true);
??????? Response.Write("用戶(hù)名:" + Profile.UserName);
??????? Response.Write("購(gòu)物情況:" + Profile.Person.Cart);
??? }
或許我們以為:點(diǎn)擊Click提交以后自然會(huì)把a(bǔ)bc賦值給UserName屬性,并且一同把數(shù)值帶來(lái)了,但是實(shí)際并非我們想象那么簡(jiǎn)單:結(jié)果你會(huì)發(fā)現(xiàn)“用戶(hù)名”雖然是abc,但是Cart卻空了(丟失數(shù)據(jù)了?)
這里的原因非常簡(jiǎn)單:因?yàn)镻rofile在匿名存儲(chǔ)數(shù)據(jù)的時(shí)候,會(huì)發(fā)送一個(gè)隨機(jī)的Cookie給客戶(hù)端(Id是唯一的),然后寫(xiě)入數(shù)值。但是你登錄以后,原先的憑證就被作廢,自動(dòng)換一個(gè)新的憑證了。所以解決方案就是在SetAuthCookie的時(shí)候必須獲取原來(lái)那個(gè)即將丟失的憑據(jù),然后賦值給當(dāng)前的Profile。
這里提供一個(gè)解決方案(在Global.asax加入以下代碼):
? void Profile_MigrateAnonymous(Object s,
?? ???ProfileMigrateEventArgs e)
??? {
??????? ProfileCommon anonProfile = Profile.GetProfile(e.AnonymousID);????????? //通過(guò)該方法將獲得匿名用戶(hù)的Profile
??????? Profile.Person.Cart = anonProfile.Person.Cart;?? //重新賦值給當(dāng)前的Profile
??? }??
(六)Profile的清理工作
??????????? 你的網(wǎng)站曾經(jīng)被大量的“匿名”和“登錄”用戶(hù)訪(fǎng)問(wèn),結(jié)果造成你的aspnet_profile數(shù)據(jù)庫(kù)中擠滿(mǎn)了一堆不需要的垃圾數(shù)據(jù)。您可以清理。清理的方法當(dāng)然也是直接使用ProfileManager.DeleteInactiveProfiles,其具體參數(shù)如下:
ProfileManager.DeleteInactiveProfiles(ProfileAuthenticationOption.All, DateTime.Now.AddDays(-7));
其中“ProfileAuthenticationOption”是一個(gè)枚舉,指示刪除的Profile的范圍(全部All,登錄用戶(hù)Authenticated和匿名用戶(hù)Anoymous)。而DateTime是刪除在此日期前(包括此日期自身)的Profile,如上面的代碼所示:刪除距離現(xiàn)在7天前的所有用戶(hù)的Profile。
轉(zhuǎn)載于:https://www.cnblogs.com/serviceboy/archive/2010/04/23/1718417.html
總結(jié)
以上是生活随笔為你收集整理的ASP.NET专题研究——角色和Profile的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 一步一步学Silverlight 2系列
- 下一篇: 程序员的语言“艳遇史”(一)——班长pa