国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 開(kāi)發(fā) > 綜合 > 正文

ViewState 到底是什么?

2024-07-21 02:17:00
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
asp.net viewstate 初探 susan warren microsoft corporation 2001 年 11 月 27 日 與剛接觸 asp.net 頁(yè)面的開(kāi)發(fā)人員交談時(shí),他們通常向我提出的第一個(gè)問(wèn)題就是:“那個(gè) viewstate 到底是什么?”他們的語(yǔ)氣中流露出的那種感覺(jué),就象我來(lái)到一家異國(guó)情調(diào)的餐館,侍者端上一道我從未見(jiàn)過(guò)的菜肴時(shí)的那種感覺(jué) - 既疑惑不解,又充滿好奇。但肯定有人認(rèn)為它不錯(cuò),否則就不會(huì)提供了。所以,我會(huì)先嘗一嘗,或許會(huì)喜歡上它,盡管它看上去的確很古怪!對(duì)于 viewstate 也是如此,但是如果適應(yīng)了它的風(fēng)格,您會(huì)發(fā)現(xiàn)在許多情況下,您將樂(lè)于在自己的 asp.net 應(yīng)用程序中使用 viewstate,因?yàn)樗梢詭椭褂酶俚拇a完成更多的工作。但是,有時(shí)也會(huì)對(duì) viewstate 完全棄之不用。下面我們就這兩種情況分別進(jìn)行闡述,不過(guò),讓我們先回答什么是 viewstate 這個(gè)問(wèn)題。

答案:viewstate 用于維護(hù)頁(yè)面的 ui 狀態(tài)

web 是沒(méi)有狀態(tài)的,asp.net 頁(yè)面也沒(méi)有狀態(tài),它們?cè)诘椒?wù)器的每個(gè)往返過(guò)程中被實(shí)例化、執(zhí)行、呈現(xiàn)和處理。作為 web 開(kāi)發(fā)人員,您可以使用眾所周知的技術(shù)(如以會(huì)話狀態(tài)將狀態(tài)存儲(chǔ)在服務(wù)器上,或?qū)㈨?yè)面回傳到自身)來(lái)添加狀態(tài)。下面我們以圖 1 中的注冊(cè)窗體為例進(jìn)行論述。 圖 1:恢復(fù)回傳的窗體值 從上圖中可以看出,我為便餐選擇了一個(gè)無(wú)效的值。此窗體與 web 上的多數(shù)窗體一樣友好,它在出現(xiàn)錯(cuò)誤的字段旁邊顯示一條有用的錯(cuò)誤消息和一個(gè)星號(hào)。而且,窗體中還顯示了我在其他文本框和下拉列表中輸入的所有有效值。這在某種程度上是可能的,因?yàn)?html 窗體元素會(huì)在 http 標(biāo)頭中將其當(dāng)前值從瀏覽器發(fā)送到服務(wù)器。您可以使用 asp.net 跟蹤來(lái)查看回傳的窗體值,如圖 2 所示。 圖 2:http 窗體中回傳的值(通過(guò) asp.net 跟蹤顯示) 在 asp.net 之前,通過(guò)多次回傳將值恢復(fù)到窗體字段中完全是頁(yè)面開(kāi)發(fā)人員的責(zé)任,他們將不得不從 http 窗體中逐個(gè)拾取回傳值,然后再將其推回字段中。幸運(yùn)的是,現(xiàn)在 asp.net 可以自動(dòng)完成這項(xiàng)任務(wù),從而為開(kāi)發(fā)人員免除了一項(xiàng)令人厭煩的工作,同時(shí)也無(wú)需再為窗體編寫(xiě)大量的代碼。但這并不是 viewstate。 viewstate(英文)是一種機(jī)制,asp.net 使用這種機(jī)制來(lái)跟蹤服務(wù)器控件狀態(tài)值,否則這些值將不作為 http 窗體的一部分而回傳。例如,由 label 控件顯示的文本默認(rèn)情況下就保存在 viewstate 中。作為開(kāi)發(fā)人員,您可以綁定數(shù)據(jù),或在首次加載該頁(yè)面時(shí)僅對(duì) label 編程設(shè)置一次,在后續(xù)的回傳中,該標(biāo)簽文本將自動(dòng)從 viewstate 中重新填充。因此,除了可以減少繁瑣的工作和代碼外,viewstate 通常還可以減少數(shù)據(jù)庫(kù)的往返次數(shù)。

viewstate 的工作原理

viewstate 確實(shí)沒(méi)有什么神秘之處,它是由 asp.net 頁(yè)面框架管理的一個(gè)隱藏的窗體字段。當(dāng) asp.net 執(zhí)行某個(gè)頁(yè)面時(shí),該頁(yè)面上的 viewstate 值和所有控件將被收集并格式化成一個(gè)編碼字符串,然后被分配給隱藏窗體字段的值屬性(即 )。由于隱藏窗體字段是發(fā)送到客戶端的頁(yè)面的一部分,所以 viewstate 值被臨時(shí)存儲(chǔ)在客戶端的瀏覽器中。如果客戶端選擇將該頁(yè)面回傳給服務(wù)器,則 viewstate 字符串也將被回傳。在上面的圖 2 中可以看到 viewstate 窗體字段及其回傳的值。回傳后,asp.net 頁(yè)面框架將解析 viewstate 字符串,并為該頁(yè)面和各個(gè)控件填充 viewstate 屬性。然后,控件再使用 viewstate 數(shù)據(jù)將自己重新恢復(fù)為以前的狀態(tài)。關(guān)于 viewstate 還有三個(gè)值得注意的小問(wèn)題。
  1. 如果要使用 viewstate,則在 aspx 頁(yè)面中必須有一個(gè)服務(wù)器端窗體標(biāo)記 ()。窗體字段是必需的,這樣包含 viewstate 信息的隱藏字段才能回傳給服務(wù)器。而且,該窗體還必須是服務(wù)器端的窗體,這樣在服務(wù)器上執(zhí)行該頁(yè)面時(shí),asp.net 頁(yè)面框架才能添加隱藏的字段。
  2. 頁(yè)面本身將 20 字節(jié)左右的信息保存在 viewstate 中,用于在回傳時(shí)將 postback 數(shù)據(jù)和 viewstate 值分發(fā)給正確的控件。因此,即使該頁(yè)面或應(yīng)用程序禁用了 viewstate,仍可以在 viewstate 中看到少量的剩余字節(jié)。
  3. 在頁(yè)面不回傳的情況下,可以通過(guò)省略服務(wù)器端的 標(biāo)記來(lái)去除頁(yè)面中的 viewstate。

充分利用 viewstate

viewstate 為跨回傳跟蹤控件的狀態(tài)提供了一條神奇的途徑,因?yàn)樗皇褂梅?wù)器資源、不會(huì)超時(shí),并且適用于任何瀏覽器。如果您要編寫(xiě)控件,那么肯定需要了解如何在控件中維護(hù)狀態(tài)(英文)。開(kāi)發(fā)人員在編寫(xiě)頁(yè)面時(shí)同樣可以按照幾乎相同的方式來(lái)利用 viewstate,只是有時(shí)頁(yè)面會(huì)包含不由控件存儲(chǔ)的 ui 狀態(tài)值。您可以跟蹤 viewstate 中的值,使用的編程語(yǔ)法與會(huì)話和高速緩存的語(yǔ)法類(lèi)似:

[visual basic]

' 保存在 viewstate 中viewstate("sortorder") = "desc"' 從 viewstate 中讀取dim sortorder as string = cstr(viewstate("sortorder"))

[c#]

// 保存在 viewstate 中viewstate["sortorder"] = "desc";// 從 viewstate 中讀取string sortorder = (string)viewstate["sortorder"];
請(qǐng)看下面的示例:要在 web 頁(yè)上顯示一個(gè)項(xiàng)目列表,而每個(gè)用戶需要不同的列表排序。項(xiàng)目列表是靜態(tài)的,因此可以將這些頁(yè)面綁定到相同的緩存數(shù)據(jù)集,而排序順序只是用戶特定的 ui 狀態(tài)的一小部分。viewstate 非常適合于存儲(chǔ)這種類(lèi)型的值。代碼如下:

[visual basic]

                                        

                在 viewstate 中存儲(chǔ)非控件狀態(tài)            

            
                此示例將一列靜態(tài)數(shù)據(jù)的當(dāng)前排序順序存儲(chǔ)在 viewstate 中。
                單擊列標(biāo)題中的鏈接,可按該字段排序數(shù)據(jù)。
                再次單擊該鏈接,將按相反順序排序。                


                                                                                                
下面是上述兩個(gè)代碼段中引用的 testdata.xml 的代碼:
  0736    new moon books    boston    ma    usa    0877    binnet & hardley    washington    dc    usa    1389    algodata infosystems    berkeley    ca    usa    1622    five lakes publishing    chicago    il    usa    1756    ramona publishers    dallas    tx    usa    9901    ggg&g    muenchen    germany    9952    scootney books    new york    ny    usa    9999    lucerne publishing    paris    france  

選擇會(huì)話狀態(tài)還是 viewstate?

在某些情況下,將狀態(tài)值保存在 viewstate 中并不是最佳選擇,最常用的替代方法就是會(huì)話狀態(tài),它通常更適用于:
  • 大量的數(shù)據(jù)。由于 viewstate 增加了發(fā)送到瀏覽器的頁(yè)面的大小(html 有效負(fù)載),同時(shí)也增加了回傳的窗體的大小,因此不適合存儲(chǔ)大量數(shù)據(jù)。
  • 未在 ui 中顯示的安全數(shù)據(jù)。盡管 viewstate 數(shù)據(jù)已被編碼,并且可以選擇對(duì)其進(jìn)行加密,但始終不將數(shù)據(jù)發(fā)送到客戶端才是最安全的。因此,會(huì)話是更安全的選擇。(由于數(shù)據(jù)庫(kù)需要額外的憑據(jù)進(jìn)行驗(yàn)證,因此將數(shù)據(jù)存儲(chǔ)在數(shù)據(jù)庫(kù)中會(huì)更安全。可以添加 ssl 以獲得更安全的鏈接。)但是,如果在 ui 中已經(jīng)顯示了該專(zhuān)用數(shù)據(jù),那么您應(yīng)該已經(jīng)確認(rèn)了鏈接的安全性。在這種情況下,將同樣的值放入 viewstate 不會(huì)降低安全性。
  • 尚未序列化到 viewstate 中的對(duì)象,如 dataset。viewstate 序列化程序只為一小部分常用的對(duì)象類(lèi)型進(jìn)行了優(yōu)化,如下所示。其他可序列化的類(lèi)型或許可以保留在 viewstate 中,但速度會(huì)變慢,并會(huì)生成一個(gè)非常大的 viewstate。
會(huì)話狀態(tài)viewstate是否使用服務(wù)器資源?是否是否超時(shí)?是,20 分鐘后(默認(rèn))否是否存儲(chǔ)所有 .net 類(lèi)型?是否,僅支持:string、integer、boolean、array、arraylist、hashtable 和自定義 typeconverter是否增加“html 有效負(fù)載”?否是

使用 viewstate 獲得最佳性能

使用 viewstate 時(shí),每個(gè)對(duì)象都必須先序列化到 viewstate 中,然后再通過(guò)回傳進(jìn)行反序列化,因此使用 viewstate 并非是沒(méi)有代價(jià)的。但是,如果遵循某些簡(jiǎn)單的原則對(duì) viewstate 的成本加以控制,則通常不會(huì)產(chǎn)生明顯的性能影響。
  • 在不需要時(shí)禁用 viewstate。下面的“減少使用 viewstate”一節(jié)將詳細(xì)介紹這一問(wèn)題。
  • 使用優(yōu)化過(guò)的 viewstate 序列化程序。上面列出的類(lèi)型具有專(zhuān)門(mén)的序列化程序,這些程序運(yùn)行速度很快,并已經(jīng)過(guò)優(yōu)化,可以生成很小的 viewstate。如果要序列化一個(gè)未在上面列出的類(lèi)型,可以創(chuàng)建一個(gè)自定義 typeconverter 來(lái)顯著提高它的性能。
  • 盡量減少使用對(duì)象,如果可能,盡量減少放入 viewstate 中的對(duì)象的數(shù)目。例如,不要使用二維字符串?dāng)?shù)組(名稱(chēng)/值,其對(duì)象的數(shù)目與數(shù)組的長(zhǎng)度一樣多),而應(yīng)使用兩個(gè)字符串?dāng)?shù)組(只有兩個(gè)對(duì)象)。但是,在將兩個(gè)已知類(lèi)型存儲(chǔ)在 viewstate 中之前,在這兩者之間轉(zhuǎn)換不會(huì)獲得任何性能提高,因?yàn)檫@樣做實(shí)際上相當(dāng)于付出了兩次轉(zhuǎn)換的代價(jià)。

減少使用 viewstate

默認(rèn)情況下 viewstate 將被啟用,并且是由每個(gè)控件(而非頁(yè)面開(kāi)發(fā)人員)來(lái)決定存儲(chǔ)在 viewstate 中的內(nèi)容。有時(shí),這一信息對(duì)應(yīng)用程序并沒(méi)有什么用處。盡管也沒(méi)什么害處,但卻會(huì)明顯增加發(fā)送到瀏覽器的頁(yè)面的大小。因此如果不需要使用 viewstate,最好還是將它關(guān)閉,特別是當(dāng) viewstate 很大的時(shí)候。可以基于每個(gè)控件、每個(gè)頁(yè)面或每個(gè)應(yīng)用程序來(lái)關(guān)閉 viewstate。在以下情況中將不再需要 viewstate:頁(yè)面控件
  • 頁(yè)面不回傳給自身。
  • 處理的不是控件的事件。
  • 控件沒(méi)有動(dòng)態(tài)的或數(shù)據(jù)綁定的屬性值(或?qū)τ诿恳粋€(gè)請(qǐng)求它們都設(shè)置在代碼中)。
datagrid 控件是 viewstate 的一個(gè)重量級(jí)用戶。默認(rèn)情況下,在網(wǎng)格中顯示的所有數(shù)據(jù)也都存儲(chǔ)在 viewstate 中,當(dāng)需要一個(gè)復(fù)雜的操作(如復(fù)雜的搜索)來(lái)獲取數(shù)據(jù)時(shí),這是非常有用的。但是,datagrid 的這種行為有時(shí)也使得 viewstate 成為累贅。例如,這里有一個(gè)簡(jiǎn)單的頁(yè)面就屬于上述情況。因?yàn)轫?yè)面不回傳給自身,所以它并不需要 viewstate。 圖 3:帶有 datagrid1 的簡(jiǎn)單頁(yè)面 lessviewstate.aspx
                                    
啟用 viewstate 時(shí),這個(gè)小網(wǎng)格會(huì)給該頁(yè)面增加 3000 多字節(jié)的 html 有效負(fù)載!使用 asp.net tracing(英文)或查看發(fā)送到瀏覽器的頁(yè)面的源代碼(如以下代碼所示),可以清楚地看到這一點(diǎn)。
                        
看!只是禁用了該網(wǎng)格的 viewstate,同一頁(yè)面的有效負(fù)載就大大減少了:
                        
下面是 visual basic 和 c# 的完整的 lessviewstate 代碼:

[visual basic]

                                        

                通過(guò)禁用 viewstate 來(lái)減少頁(yè)面的“html 有效負(fù)載”            

            
                                                                                                

[c#]

                                        

                通過(guò)禁用 viewstate 來(lái)減少頁(yè)面的“html 有效負(fù)載”            

            
                                                                                                

禁用 viewstate

在上述示例中,我通過(guò)將網(wǎng)格的 enableviewstate 屬性設(shè)置為 false 禁用了 viewstate。可以針對(duì)單個(gè)控件、整個(gè)頁(yè)面或整個(gè)應(yīng)用程序禁用 viewstate,如下所示:每個(gè)控件(在標(biāo)記上)每個(gè)頁(yè)面(在指令中)每個(gè)應(yīng)用程序(在 web.config 中)

使 viewstate 更安全

由于 viewstate 沒(méi)有被格式化為清晰的文本,某些人有時(shí)會(huì)認(rèn)為它被加密了,其實(shí)并沒(méi)有。相反,viewstate 只是進(jìn)行了 base64 編碼,以確保值在往返過(guò)程中不會(huì)發(fā)生變化,而并不考慮應(yīng)用程序使用的響應(yīng)/請(qǐng)求編碼。可以向應(yīng)用程序中添加兩種 viewstate 安全級(jí)別:
  • 防篡改
  • 加密
需要注意的是,viewstate 安全性對(duì)于處理和呈現(xiàn) asp.net 頁(yè)面所需的時(shí)間有直接的影響。簡(jiǎn)單地說(shuō),安全性越高,速度越慢。因此如果不需要,請(qǐng)不要為 viewstate 添加安全性。

防篡改

盡管散列代碼不能確保 viewstate 字段中實(shí)際數(shù)據(jù)的安全,但它能夠顯著降低有人通過(guò) viewstate 騙過(guò)應(yīng)用程序的可能性,即防止回傳應(yīng)用程序通常禁止用戶輸入的值。可以通過(guò)設(shè)置 enableviewstatemac 屬性來(lái)指示 asp.net 向 viewstate 字段中追加一個(gè)散列代碼:
可以在頁(yè)面級(jí)別上設(shè)置 enableviewstatemac,也可以在應(yīng)用程序級(jí)別上設(shè)置。在回傳時(shí),asp.net 將為 viewstate 數(shù)據(jù)生成一個(gè)散列代碼,并將其與存儲(chǔ)在回傳值中的散列代碼進(jìn)行比較。如果兩處的散列代碼不匹配,該 viewstate 數(shù)據(jù)將被丟棄,同時(shí)控件將恢復(fù)為原來(lái)的設(shè)置。默認(rèn)情況下,asp.net 使用 sha1 算法來(lái)生成 viewstate 散列代碼。此外,也可以通過(guò)在 machine.config 文件中設(shè)置 來(lái)選擇 md5 算法,如下所示:

加密

可以使用加密來(lái)保護(hù) viewstate 字段中的實(shí)際數(shù)據(jù)值。首先,必須如上所述設(shè)置 enableviewstatmac="true"。然后,將 machinekey validation 類(lèi)型設(shè)置為 3des。這將指示 asp.net 使用 triple des 對(duì)稱(chēng)加密算法來(lái)加密 viewstate 值。

web 領(lǐng)域中的 viewstate 安全性

默認(rèn)情況下,asp.net 將創(chuàng)建一個(gè)隨機(jī)的驗(yàn)證密鑰,并存儲(chǔ)在每個(gè)服務(wù)器的本地安全授權(quán) (lsa) 中。要驗(yàn)證在另一臺(tái)服務(wù)器上創(chuàng)建的 viewstate 字段,兩臺(tái)服務(wù)器的 validationkey 必須設(shè)置為相同的值。如果要通過(guò)上述方式之一,對(duì)運(yùn)行于 web 領(lǐng)域配置中的應(yīng)用程序進(jìn)行 viewstate 安全設(shè)置,則需要為所有服務(wù)器提供一個(gè)唯一的、共享的驗(yàn)證密鑰。驗(yàn)證密鑰是一個(gè)包含 20 到 64 位密碼增強(qiáng)字節(jié)的隨機(jī)字符串,用 40 到 128 個(gè)十六進(jìn)制字符表示。密鑰越長(zhǎng)越安全,因此建議使用 128 個(gè)字符的密鑰(如果計(jì)算機(jī)支持)。例如:
 [/b]validationkey=" f3690e7a3143c185ab1089616a8b4d81fd55dd7a69eeaa3b32a6ae813eceecd28dea66a23bee42193729bd48595ebafe2c2e765be77e006330bc3b1392d7c73f" />
system.security.cryptography 名稱(chēng)空間包括 rngcryptoserviceprovider 類(lèi),使用該類(lèi)可以生成此字符串,如以下 generatecryptokey.aspx 示例所示:
                    

生成隨機(jī)加密密鑰

        
                            40-byte                128-byte                                             
                        復(fù)制并粘貼生成的結(jié)果            

總結(jié)

asp.net viewstate 是一種新的狀態(tài)服務(wù),可供開(kāi)發(fā)人員基于每個(gè)用戶來(lái)跟蹤 ui 狀態(tài)。viewstate 沒(méi)有什么神秘之處,它只是利用了一個(gè)老的 web 編程技巧:在一個(gè)隱藏的窗體字段中來(lái)回傳遞狀態(tài),并將它直接應(yīng)用于頁(yè)面處理框架中。但效果卻非常好 - 在基于 web 的窗體中只需編寫(xiě)并維護(hù)很少的代碼。用戶可能并不總是需要它,但我想您在需要它的時(shí)候會(huì)發(fā)現(xiàn),viewstate 是提供給頁(yè)面開(kāi)發(fā)人員的諸多 asp.net 新功能中非常令人滿意的一種功能。 
  • 本文來(lái)源于網(wǎng)頁(yè)設(shè)計(jì)愛(ài)好者web開(kāi)發(fā)社區(qū)http://www.html.org.cn收集整理,歡迎訪問(wèn)。
  • 發(fā)表評(píng)論 共有條評(píng)論
    用戶名: 密碼:
    驗(yàn)證碼: 匿名發(fā)表
    主站蜘蛛池模板: 宾阳县| 邳州市| 合阳县| 油尖旺区| 肇庆市| 四子王旗| 南康市| 宁远县| 太仆寺旗| 南皮县| 泰顺县| 浦东新区| 会同县| 丰都县| 博客| 壤塘县| 精河县| 银川市| 昌邑市| 繁昌县| 九江市| 沈阳市| 修文县| 五大连池市| 大荔县| 天长市| 阿克苏市| 南靖县| 临漳县| 乌审旗| 无锡市| 宿松县| 上杭县| 霍州市| 界首市| 三都| 略阳县| 阜南县| 长沙县| 龙里县| 阜平县|