asp.net 控件的開(kāi)發(fā)人員利用 viewstate 和控件狀態(tài)來(lái)保持瀏覽器發(fā)出的各請(qǐng)求之間的狀態(tài)信息。通常,該信息作為由頁(yè)面呈現(xiàn)的 html 標(biāo)記中的隱藏字段傳送給客戶端。然后,該頁(yè)面狀態(tài)作為下一個(gè)窗體提交的一部分傳回服務(wù)器并還原給控件或頁(yè)面。即使瀏覽器使用 http 協(xié)議(該協(xié)議定義為無(wú)狀態(tài)),但利用臨時(shí)存儲(chǔ)狀態(tài)信息的功能,控件的開(kāi)發(fā)人員能夠輕松地提供更豐富的應(yīng)用程序體驗(yàn)。
asp.net 2.0 允許您修改臨時(shí)保持頁(yè)面狀態(tài)的位置和方式。在某些情況下,避免在客戶端與服務(wù)器之間往返傳送數(shù)據(jù)可能更為可取。asp.net 2.0 提供的兩個(gè)頁(yè)面狀態(tài)持續(xù)程序分別是 hiddenfieldpagestate 持續(xù)程序(我們已提到過(guò))和 sessionpagestatepersister。sessionpagestatepersister 利用與瀏覽器會(huì)話相關(guān)的服務(wù)器會(huì)話存儲(chǔ)數(shù)據(jù)。使用 sessionpagestatepersister 有正反兩個(gè)方面。對(duì)于發(fā)送到(自)瀏覽器的頁(yè)面而言,使用會(huì)話(而非隱藏字段)可以避免其大小的增加。在許多情況中,頁(yè)面狀態(tài)是全部標(biāo)記的一個(gè)重要部分。然而,在會(huì)話中存儲(chǔ)數(shù)據(jù)將占用寶貴的服務(wù)器資源。此外,隱藏字段不像會(huì)話那樣具有相關(guān)的超時(shí)。您可以配置一個(gè)應(yīng)用程序,以便將會(huì)話保持到后端數(shù)據(jù)庫(kù),并避免將負(fù)載直接加到 web 服務(wù)器。這也將擴(kuò)展至 web 場(chǎng)方案。
要使用除默認(rèn)持續(xù)程序之外的持續(xù)程序,需要重寫該頁(yè)的 pagestatepersister 屬性,并返回另一個(gè)持續(xù)程序的一個(gè)實(shí)例。首先,下面的一個(gè)簡(jiǎn)單頁(yè)面只使用大量數(shù)字填充一個(gè) arraylist,然后將它綁定到一個(gè) gridview 控件。
<!doctype html public "-//w3c//dtd xhtml 1.0 transitional//en" 
"http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd">
<script runat="server">
    protected override pagestatepersister pagestatepersister {
        get {
            return new sessionpagestatepersister(this);
        }
    }
    protected override void onload(eventargs e) {
        base.onload(e);
        if (!ispostback) {
            arraylist list = new arraylist();
            for (int i = 0; i < 1000; i++)
            {
                list.add(convert.tostring(i));
            }
            gridview1.datasource = list;
            gridview1.databind();      
        }
    }
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="head1" runat="server">
    <title>untitled page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:gridview id="gridview1" runat="server" />        
        <asp:button id="button1" runat="server" text="submit" /></div>
    </form>
</body>
</html>
當(dāng)查看該頁(yè)面所呈現(xiàn)的 html 時(shí),您會(huì)看到一個(gè)用于傳送 viewstate 的較大隱藏字段。
<!doctype html public "-//w3c//dtd xhtml 1.0 transitional//en" 
"http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head><title>
   untitled page
</title></head>
<body>
    <form name="form1" method="post" action="default2.aspx" id="form1">
<div>
<input type="hidden" name="__viewstate" id="__viewstate" 
value="/wepdwukmtq0mdqznjk2ng9kfgicba9kfgicaq88kwanagapfgyec18hrgf0yujv
dw5kzx4jugfnzunvdw50ageec18hsxrlbunvdw50ahrkdbqraaewbh4evhlwzrkrah4etmf
tzquesxrlbr4jrgf0yuzpzwxkbqehfgjmd2qwkgibd2qwamypdxychgruzxh0bqewzgqcag
9kfgjmdw8wah8gbqexzgqcaw9kfgjmdw8wah8gbqeyzgqcba9kfgjmdw8wah8gbqezzgqcb
q9kfgjmdw8wah8gbqe0zgqcbg9kfgjmdw8wah8gbqe1zgqcbw9kfgjmdw8wah8gbqe2zgqc
ca9kfgjmdw8wah8gbqe3zgqccq9kfgjmdw8wah8gbqe4zgqccg9kfgjmdw8wah8gbqe5zgq
ccw9kfgjmdw8wah8gbqixmgrkagwpzbyczg8pfgifbgucmtfkzaind2qwamypdxychwyfaj
eyzgqcdg9kfgjmdw8wah8gbqixm2rkag8pzbyczg8pfgifbgucmtrkzaiqd2qwamypdxych
wyfaje1zgqceq9kfgjmdw8wah8gbqixnmrkahipzbyczg8pfgifbgucmtdkzaitd2qwamyp
dxychwyfaje4zgqcfa9kfgjmdw8wah8gbqixowrkahupdxychgdwaxnpymxlagrkgaefcud
yawrwawv3mq9nzmhhz3iqzp62s8ir8ftj5zl42ira" />
</div>
...
當(dāng)我們向 pagestatepersister 屬性添加重寫并使用內(nèi)置 sessionpagestatepersister 時(shí),該頁(yè)面的行為保持不變,但是用于大量狀態(tài)數(shù)據(jù)的存儲(chǔ)將從隱藏字段轉(zhuǎn)換為會(huì)話狀態(tài)。
    protected override pagestatepersister pagestatepersister
    {
        get
        {
            return new sessionpagestatepersister(this);
        }
    }
請(qǐng)注意,在該頁(yè)面的源代碼中,隱藏字段值要小得多,但并沒(méi)有完全消失。asp.net 仍將在頁(yè)面輸出中傳送一些最小的數(shù)據(jù)集。
<input type="hidden" name="__viewstate" id="__viewstate" 
value="/wepaa8fdzhjnzkyntmznje1yweynxgbbqlhcmlkvmlldzepz2qzw
44jljfcglwrl9tinlie82yauq==" />
在某些方案中,您可能只想將與之類似的代碼添加到一個(gè)較小的頁(yè)面集中,因此添加與之類似的簡(jiǎn)單重寫也許是可接受的。當(dāng)您希望一個(gè)完整的應(yīng)用程序或一個(gè)較大的頁(yè)面集擁有該行為時(shí),需要一個(gè)用于控制它的更集中化的方式。有幾種方式可以實(shí)現(xiàn)這一點(diǎn)。我們可以將創(chuàng)建該持續(xù)程序的代碼移動(dòng)到從頁(yè)面繼承的類中:
using system;
using system.data;
using system.configuration;
using system.web;
using system.web.security;
using system.web.ui;
using system.web.ui.webcontrols;
using system.web.ui.webcontrols.webparts;
using system.web.ui.htmlcontrols;
public class pagepersisterbasepage : page
{
    public pagepersisterbasepage()   {
    }
    protected override pagestatepersister pagestatepersister {
        get {
            return new sessionpagestatepersister(this);
        }
    }
} 
asp.net 2.0 使您能夠使用“inherits”頁(yè)面指令指定頁(yè)面的基類型。然后,asp.net 為該頁(yè)面生成的代碼從該基頁(yè)面繼承,而且無(wú)需在每個(gè)頁(yè)面中復(fù)制該代碼。
<%@ page language="c#" inherits="pagepersisterbasepage" %>
此外,配置選項(xiàng)使我們能夠設(shè)置頁(yè)面位置,以便所有頁(yè)面使用單一的基頁(yè)面類型。在該 web.config 頁(yè)中,我們?cè)O(shè)置了 pagebasetype,并且無(wú)需將 inherits 屬性添加到任何頁(yè)面來(lái)獲取自定義的 pagestatepersister 行為。
<?xml version="1.0"?>
<configuration>
   <system.web>
    <pages pagebasetype="pagepersisterbasepage" />
   </system.web>
</configuration>
更改 pagestatepersister 并不是一件輕松的事。請(qǐng)仔細(xì)考慮您的應(yīng)用程序和部署。盡管在隱藏字段中往返傳送 viewstate 存在相關(guān)的開(kāi)銷,但是要將狀態(tài)保持在那里,則需要有直接的服務(wù)器資源消耗。通過(guò)前面的示例您可以看到,可以插入自定義持續(xù)程序以便將狀態(tài)存儲(chǔ)在其他地方,例如,后端數(shù)據(jù)庫(kù)或 web 場(chǎng)共享的狀態(tài)服務(wù)。此外,正如我們所演示的,您可以集中控制應(yīng)用程序的行為,或者按頁(yè)在頁(yè)面上進(jìn)行控制。
新聞熱點(diǎn)
疑難解答
圖片精選