0、引言
web 頁(yè)面是無(wú)狀態(tài)的, 服務(wù)器對(duì)每一次請(qǐng)求都認(rèn)為來(lái)自不同用戶(hù),因此,變量的狀態(tài)在連續(xù)對(duì)同一頁(yè)面的多次請(qǐng)求之間或在頁(yè)面跳轉(zhuǎn)時(shí)不會(huì)被保留。在用asp.net 設(shè)計(jì)開(kāi)發(fā)一個(gè)web系統(tǒng)時(shí), 遇到一個(gè)重要的問(wèn)題是如何保證數(shù)據(jù)在頁(yè)面間進(jìn)行正確、安全和高效地傳送,asp.net 提供了狀態(tài)管理等多種技術(shù)來(lái)解決保存和傳遞數(shù)據(jù)問(wèn)題,以下來(lái)探討.net 下的解決此問(wèn)題的各種方法和各自的適用場(chǎng)合。
1、數(shù)據(jù)傳遞的各種方法和分析
1.1 使用querystring 方法
querystring 也叫查詢(xún)字符串, 這種方法將要傳遞的數(shù)據(jù)附加在網(wǎng)頁(yè)地址(url)后面進(jìn)行傳遞。如頁(yè)面a.aspx 跳轉(zhuǎn)到頁(yè)面b.aspx,可以用request.redirect(b.aspx?參數(shù)名稱(chēng)=參數(shù)值)方法,也可以用超鏈接:,頁(yè)面跳轉(zhuǎn)后,在目標(biāo)頁(yè)面中可用ruquest[參數(shù)名稱(chēng)]來(lái)接收參數(shù)。使用querysting 方法的優(yōu)點(diǎn)是實(shí)現(xiàn)簡(jiǎn)單, 不使用服務(wù)器資源;缺點(diǎn)是傳遞的值會(huì)顯示在瀏覽器的地址欄上,有被篡改的風(fēng)險(xiǎn),不能傳遞對(duì)象,只有在通過(guò)url 請(qǐng)求頁(yè)時(shí)查詢(xún)字符串才是可行的。
1.2 利用隱藏域
隱藏域不會(huì)顯示在用戶(hù)的瀏覽器中, 一般是在頁(yè)面中加入一個(gè)隱藏控件, 與服務(wù)器進(jìn)行交互時(shí)把值賦給隱藏控件并提交給下一頁(yè)面。隱藏域可以是任何存儲(chǔ)在網(wǎng)頁(yè)中的與網(wǎng)頁(yè)有關(guān)的信息的存儲(chǔ)庫(kù)。使用隱藏域存入數(shù)值時(shí)用:hidden 控件.value=數(shù)值,取出接收數(shù)值時(shí)用:變量=hidden 控件.value。使用隱藏域的優(yōu)點(diǎn)是實(shí)現(xiàn)簡(jiǎn)單, 隱藏域是標(biāo)準(zhǔn)的html 控件,不需要復(fù)雜的編程邏輯。隱藏域在頁(yè)上存儲(chǔ)和讀取,不需要任何服務(wù)器資源,幾乎所有瀏覽器和客戶(hù)端設(shè)備都支持具有隱藏域的窗體。缺點(diǎn)是存儲(chǔ)結(jié)構(gòu)少,僅僅支持簡(jiǎn)單的數(shù)據(jù)結(jié)構(gòu),存儲(chǔ)量少,因?yàn)樗淮鎯?chǔ)在頁(yè)面本身,所以無(wú)法存儲(chǔ)較大的值,而且大的數(shù)據(jù)量會(huì)受到防火墻和代理的阻止。
1.3 viewstate
viewstate 是由asp.net 頁(yè)面框架管理的一個(gè)隱藏的窗體字段。當(dāng)asp.net 執(zhí)行某個(gè)頁(yè)面時(shí),該頁(yè)面上的viewstate 值和所有控件將被收集并格式化成一個(gè)編碼字符串, 然后被分配給隱藏窗體字段的值屬性。使用viewstate 傳遞數(shù)據(jù)時(shí)可用:viewstate [ 變量名]=數(shù)值,在取出數(shù)據(jù)時(shí)用:變量=viewstate[變量名]。使用viewstate 的優(yōu)點(diǎn)是:在對(duì)同一頁(yè)的多個(gè)請(qǐng)求間自動(dòng)保留值,不用服務(wù)器端資源,實(shí)現(xiàn)簡(jiǎn)單,視圖狀態(tài)中的值經(jīng)過(guò)哈希計(jì)算和壓縮,并且針對(duì)unicode 實(shí)現(xiàn)進(jìn)行編碼,其安全性要高于使用隱藏域;缺點(diǎn)是因?yàn)関iewstate 存儲(chǔ)在頁(yè)面本身,因此如果
存儲(chǔ)較大的值,用戶(hù)顯示頁(yè)和發(fā)送頁(yè)時(shí)的速度可能會(huì)減慢。雖然視圖狀態(tài)以哈希格式存儲(chǔ)數(shù)據(jù),但它仍可以被篡改。
1.4 使用cookie
cookie 可以在頁(yè)面之間傳遞少量信息, 可以存儲(chǔ)在客戶(hù)端的文本文件中,也可存儲(chǔ)在客戶(hù)端的內(nèi)存中。cookie 方法適用于存儲(chǔ)少量頁(yè)面中經(jīng)常改動(dòng)的信息, 如為登陸過(guò)的網(wǎng)站保存登陸用戶(hù)名,為用戶(hù)輸入提供方便,還有在一些用戶(hù)自定義項(xiàng)目上保存用戶(hù)的個(gè)性化設(shè)置。使用cookie傳遞數(shù)據(jù)時(shí)可用:response.cookies[鍵名]=鍵值;取出數(shù)據(jù)用:變量名=request.cookies[鍵名]。使用cookie 優(yōu)點(diǎn)是:cookie 存儲(chǔ)在客戶(hù)端, 不使用服務(wù)器資源,實(shí)現(xiàn)簡(jiǎn)單,可配置到期時(shí)間。缺點(diǎn)是:可以存儲(chǔ)的數(shù)據(jù)量比較少,由于cookie 并不被所有的瀏覽器支持,而且還可能被用戶(hù)禁止或刪除,所以不能用于保存關(guān)鍵數(shù)據(jù)。另外,cookie 保存的形式是簡(jiǎn)單的明文文本,在它里面不宜保存敏感的、未加密的
數(shù)據(jù)。
1.5 使用application 變量
使用application 變量也可以實(shí)現(xiàn)頁(yè)面間的傳值,application變量是全局性的,所有用戶(hù)共享一個(gè)application 變量,一旦定義,它將影響到程序的所有部分。如果想在整個(gè)應(yīng)用程序范圍使用某個(gè)變量值application 對(duì)象將是最佳的選擇。存入數(shù)據(jù)時(shí), 把值添加到application 變量里:application[變量名]=數(shù)值;取出數(shù)據(jù)用:變量=application[變量名];在不需要使用該application 時(shí),要顯式清除它:application[量名]=null。
application 優(yōu)點(diǎn):易于使用,全局范圍??晒?yīng)用程序中的所有頁(yè)來(lái)訪問(wèn)。缺點(diǎn):若保存數(shù)據(jù)的服務(wù)器端進(jìn)程被損壞(如因服務(wù)器崩潰、升級(jí)或關(guān)閉而損壞),那么數(shù)據(jù)就會(huì)丟失,所以利用application 一定要有保底的策略;占用服務(wù)器端的內(nèi)存,這可能會(huì)影響服務(wù)器的性能以及應(yīng)用程序的可伸縮性。
1.6 使用session 變量
session 對(duì)象可以用來(lái)存儲(chǔ)需要維護(hù)的指定對(duì)話的信息,不同的客戶(hù)端生成不同的session 對(duì)象。session 用于存儲(chǔ)特定于單獨(dú)會(huì)話的短期信息。session 的使用方法和格式與application 相同。
優(yōu)點(diǎn):易于實(shí)現(xiàn),并且提供較高的安全性和持久性,可以應(yīng)對(duì)iis 重啟和輔助進(jìn)程重啟,可在多進(jìn)程中使用。缺點(diǎn)是耗用服務(wù)器端的內(nèi)存。所以不要存儲(chǔ)大量的信息。session 最常見(jiàn)的用途是與cookie 一起向web 應(yīng)用程序提供用戶(hù)標(biāo)識(shí)功能,session也可用于不支持cookie 的瀏覽器。但是,使用無(wú)cookie 的session 需要將會(huì)話標(biāo)識(shí)符放置在查詢(xún)字符串中,同樣會(huì)遇到本文在查詢(xún)字符串一節(jié)中陳述的安全問(wèn)題。
1.7 使用類(lèi)的靜態(tài)屬性
這種方法是利用類(lèi)的靜態(tài)屬性實(shí)現(xiàn)兩個(gè)頁(yè)面間的值傳。定義一個(gè)包含靜態(tài)屬性的類(lèi);將要傳送的值賦給靜態(tài)屬性;目標(biāo)頁(yè)面中可以通過(guò)靜態(tài)屬性獲得源頁(yè)面中要傳的值。
優(yōu)點(diǎn)是可以方便傳送多個(gè)數(shù)據(jù),缺點(diǎn)是需要額外編程,增加
程序設(shè)計(jì)的工作量,占用服務(wù)器內(nèi)存。
1.8 使用server.transfer
通過(guò)server.transfer 方法把執(zhí)行流程從當(dāng)前的aspx 文件轉(zhuǎn)到同一服務(wù)器上的另一個(gè)aspx 頁(yè)面的同時(shí),可保留表單數(shù)據(jù)或查詢(xún)字符串,做法是把該方法的第二個(gè)參數(shù)設(shè)置成true,在第一個(gè)頁(yè)面用server.transfer(目標(biāo)頁(yè)面名.aspx,true);目標(biāo)頁(yè)面取出數(shù)據(jù)用:ruquest.form[控件名稱(chēng)]或ruquest.querystring[控件名稱(chēng)]。asp.net2.0 中還可以這樣來(lái)用,代碼如下:
previouspage pg1;
pg1=(previouspage)context.handler;
response.write(pg1.name);
說(shuō)明: 此段代碼用在目標(biāo)頁(yè)面中取出傳遞的值,previous- page 是原頁(yè)面的類(lèi)名,name 是在原頁(yè)面定義的屬性, 需要傳遞 的數(shù)據(jù)存入到此屬性中。
使用這種方法, 需要寫(xiě)一些代碼以創(chuàng)建一些屬性以便可以 在另一個(gè)頁(yè)面訪問(wèn)它, 可以在另一個(gè)頁(yè)面以對(duì)象屬性的方式來(lái) 存取數(shù)值,這個(gè)方法在頁(yè)面間值傳遞中是特別有用的,這種方法 不但簡(jiǎn)潔,同時(shí)又是面向?qū)ο蟮摹?/P>
1.9 cache
cache 具有強(qiáng)大的數(shù)據(jù)操作功能, 以鍵值對(duì)集合的形式存 儲(chǔ)數(shù)據(jù),可以通過(guò)指定關(guān)鍵字來(lái)插入和檢索數(shù)據(jù)項(xiàng)。它的基于依 賴(lài)性的終止功能, 使它能夠精確控制如何并及時(shí)更新和消除緩 存中的數(shù)據(jù)。它可以?xún)?nèi)部進(jìn)行鎖定管理,不需要象application 對(duì)象那樣使用lock()和unlock()方法進(jìn)行串行化管理。缺點(diǎn)是使用 方法較復(fù)雜,使用不當(dāng)反而降低性能.
2、不同頁(yè)面跳轉(zhuǎn)情況下可采用的傳值方法
2.1 情況一:源頁(yè)面可以跳轉(zhuǎn)到目標(biāo)頁(yè)面,源頁(yè)面?zhèn)鬟f數(shù)據(jù)給目標(biāo)頁(yè)面
使用查詢(xún)字符串, 將少量信息從一頁(yè)傳輸?shù)搅硪豁?yè)以及不 存在安全性問(wèn)題時(shí),是一個(gè)簡(jiǎn)單常用的方法;使用server.transfer方法,可傳遞表單數(shù)據(jù)或查詢(xún)字符串到另一個(gè)頁(yè)面,還可以 保存初始頁(yè)的httpcontext, 當(dāng)目標(biāo)頁(yè)和源頁(yè)面在同一個(gè)服務(wù)器 時(shí),可以用此方法。
2.2 情況二:頁(yè)面?zhèn)鬟f數(shù)值給自身頁(yè)面
即在對(duì)同一頁(yè)的多個(gè)請(qǐng)求間保留值, viewstate 屬性可提供具有基本安全性的功能。也可用隱藏域,存儲(chǔ)少量回發(fā)到自身或另一頁(yè)的頁(yè)信息時(shí)使用,不考慮安全性問(wèn)題時(shí)使用。
2.3 情況三:源頁(yè)面?zhèn)鬟f數(shù)值給目標(biāo)頁(yè)面,而源頁(yè)面不能直接連接到目標(biāo)頁(yè)面。
有多個(gè)方法,具體用哪個(gè)要看具體情況。
application: 存儲(chǔ)由多個(gè)用戶(hù)使用且更改不頻繁的全局信息,此時(shí)安全性不成為問(wèn)題。不要存儲(chǔ)大量的信息。session:存儲(chǔ)特定于單獨(dú)會(huì)話的短期信息,并且需要較高的安全性。不要在會(huì)話狀態(tài)中存儲(chǔ)大量的信息。需要注意,將為應(yīng)用程序中每一會(huì)話的生存期創(chuàng)建并維護(hù)會(huì)話狀態(tài)對(duì)象。在支持許多用戶(hù)的應(yīng)用程序中, 這可能會(huì)占用大量服務(wù)器資源并影響可縮放性。
cookie: 當(dāng)您需要在客戶(hù)端存儲(chǔ)少量信息以及不存在安全性問(wèn)題時(shí)使用。類(lèi)的靜態(tài)屬性,方便傳送多個(gè)數(shù)據(jù)。
cache :對(duì)象用于單個(gè)用戶(hù)、一組用戶(hù)或所有的用戶(hù)??梢詾槎鄠€(gè)請(qǐng)求長(zhǎng)時(shí)間、高效率的保存數(shù)據(jù)。上述幾個(gè)方法, 不僅用于情況三, 前面兩種情況都可以使用,只是沒(méi)有必要時(shí)盡量少用,否則會(huì)造成資源浪費(fèi)或增加程序的復(fù)雜性。
更多信息請(qǐng)查看IT技術(shù)專(zhuān)欄