国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
ASP.Net ViewState的實現(xiàn) - 清清月兒 .NET萬花筒 Asp.net技術(shù)...
ASP.Net ViewState的實現(xiàn) 收藏
  選擇自 timmy3310 的 Blog
ViewState是.Net中提出的狀態(tài)保存的一種新途徑(實際上也是老瓶裝新酒);我們知道,傳統(tǒng)的Web程序保存狀態(tài)的方式有這樣幾種:
  1、Application 這是Web應(yīng)用程序生命期中的全局保存區(qū),保存在Application中的數(shù)據(jù)是全局有效的;在Asp.Net中,有一個應(yīng)用程序池,其中保存了數(shù)個(或數(shù)十個)應(yīng)用程序?qū)嵗恳淮握埱蠖紩某刂腥∫粋€實例來處理請求,在請求完畢之前,這個實例不會接受其他請求;這就出現(xiàn)一個問題,同一時間可能存在多個應(yīng)用程序,也就是多個線程,這些線程都存在訪問Application的可能,所以在對Application中的對象進(jìn)行處理的時候需要考慮線程同步的問題;實際上Application對象內(nèi)部實現(xiàn)了一個線程鎖,調(diào)用它本身的Add、Remove等方法的時候會自動調(diào)用加鎖和解鎖的操作,但是出于性能考慮,對于直接通過索引器或其他方式得到其中的對象并進(jìn)行操作的過程,Application并沒有自動處理線程同步,需要利用下列類似的代碼來處理:
        Application.Lock();
        ((int)Application["Count"])++;
        Application.Unlock();
    值得注意的是,調(diào)用了Lock之后,如果沒有顯示的調(diào)用Unlock,那么在這個請求結(jié)束的時候,Application對象會自動解鎖,這樣防止了造成死鎖的問題,但是為了代碼的健壯性,調(diào)用完Lock并且修改完畢應(yīng)該立即的調(diào)用Unlock方法。
Application對象本質(zhì)上就是一個Hash表,按照鍵值存放了對象,由于對象是全局并且存放在服務(wù)器,并且存在多線程同時訪問,所以,Application里面存放的應(yīng)該是訪問較多,修改較少并且是全局至少大部分功能會使用的數(shù)據(jù),例如計數(shù)器或者數(shù)據(jù)庫連接串等。
  2、Session  在Asp.Net內(nèi)部,有一個StateApplication來管理Session,實際上就是一個輔助進(jìn)程,處理Session到期、創(chuàng)建的特殊請求,在收到每一次請求的時候,輔助進(jìn)程就會調(diào)用狀態(tài)服務(wù)器(可以通過Web.config設(shè)置不同的狀態(tài)服務(wù)器)來獲取Session,如果沒有對應(yīng)該SessionId的Session,則會新建一個,然后綁定到上下文中(HttpContext);與Asp不同的是,Session的狀態(tài)服務(wù)器有多種,目前在Asp.Net內(nèi)部實現(xiàn)了三種:
      1) InProcStateClientManager 這是傳統(tǒng)的Session保存方式,但是還是有些細(xì)微差別
      2) SqlStateClientManager 這是將Session保存到數(shù)據(jù)庫方式
      3) OutOfProcStateClientManager 這是將Session保存到進(jìn)程外的方式
    Asp.Net的Session機(jī)制有一個特點,就是處理Session的輔助進(jìn)程與保存Session的狀態(tài)服務(wù)器是分開的,按照MSDN的說法,有下列好處:
      “因為用于會話狀態(tài)的內(nèi)存不在 ASP.NET 輔助進(jìn)程中,所以可以實現(xiàn)從應(yīng)用程序故障的恢復(fù)。”
      “因為所有狀態(tài)與輔助進(jìn)程不存儲在一起,您可以干凈地跨多個進(jìn)程對應(yīng)用程序進(jìn)行分區(qū)。這種分區(qū)可以顯著地提高多個進(jìn)程的計算機(jī)上應(yīng)用程序的可用性和可縮放性。”
      “因為所有狀態(tài)與輔助進(jìn)程不存儲在一起,所以您可以跨運行于多個計算機(jī)上的多個輔助進(jìn)程對應(yīng)用程序進(jìn)行分區(qū)。”
Asp.Net的Session機(jī)制個人觀點,感覺靈活性比較好,內(nèi)部實現(xiàn)也比較巧妙,但是實際上因為沒有做過多的測試,所以應(yīng)用上會不會像它說的那么美好,不敢打包票。有機(jī)會,我會單獨寫篇文章來深入的探討Asp.Net 內(nèi)部的Session機(jī)制。
  3、Cookie  這個沒甚么好說,實際上Asp.Net與Asp的Cookie沒甚么分別,也許這項技術(shù)毀譽參半,而且比較依賴客戶機(jī)實現(xiàn),MS也沒什么改進(jìn)的。
  4、ViewState 這是我們今天重點討論的;實際上ViewState并不神秘,就是一個Hidden字段,但是它是服務(wù)器控件狀態(tài)保存的基礎(chǔ);不熟悉的朋友可以用IE查看Html源碼,找到一個名為"__VIEWSTATE"的Hidden字段,其中有一大堆亂七八糟的字符,這就是頁面的ViewState。
     做過Web程序的人可能都有這種痛苦的體會,有時候為了處理頁面上面比較復(fù)雜的功能,常常會加很多Hidden,然后在服務(wù)器端用一大堆判斷來分析目前的狀態(tài),寫起來煩人,寫完了代碼更是難看;實際上,ViewState就是幫我們系統(tǒng)的實現(xiàn)了保存控件狀態(tài)的功能,服務(wù)器端控件能夠在多次請求間保存狀態(tài)也全靠它。
    好,介紹就到這里,今天我們不是討論ViewState的使用,而是從內(nèi)部來探探這個東西的本質(zhì)。
  我們首先建一個測試的頁面:
  <%@ Page language="c#" Codebehind="ViewStateTest.aspx.cs" AutoEventWireup="false" Inherits="CsdnTest.ViewStateTest" %>
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
  <html>
    <head>
  <title>ViewStateTest</title>
  <meta name="GENERATOR" Content="Microsoft Visual Studio 7.0">
  <meta name="CODE_LANGUAGE" Content="C#">
  <meta name="vs_defaultClientScript" content="JavaScript">
  <meta name="vs_targetSchema" content="    </head>
 <body>
  <form id="ViewStateTest" method="post" runat="server">
  <asp:Button ID="btnPostBack" Runat="server" Text="Post Back" Width="85px"></asp:Button>
  <br/>
  <asp:CheckBox ID="chkTest" Runat="server" Text="This is a check box"></asp:CheckBox>
  </form>
 </body>
  </html>
   注意我們使用了一個LosFormatter類,實際上這個類就是Asp.Net內(nèi)部為ViewState提供序列化的類,它有兩個方法,一個是Serialize,就是序列化一個對象,一個是Deserialize,是反序列化,我們這里使用了反序列化的方法來把ViewState直接反序列化成一個對象,然后把這個對象的類型打出來,這個對象就是:Triplet類型,實際上Asp.Net中頁面保存的ViewState就是這個類型,我們先分析一下LosFormater,再來細(xì)說.
   我們再回來看打出來的結(jié)果B:t<1256029107;;l>D3i s-! 
t,實際上通過查看LosFormatter反編譯后的代碼,大致上可以看出它序列化的方式是很簡單的,就是判斷要序列化對象的類型,如果不是直接序列化的類型,則把它的類型記錄下來,然后在遞歸序列化它的屬性,我們看B中的"t"就是表示Triplet這個類型,這個類型有三個屬性,這三個屬性包含在"<"和">"之間,用";"分割,而最后面的D3i s-! 
t據(jù)我分析應(yīng)該是一個防止ViewState被改變的Hash值,這個不是很確定,因為反編譯的代碼實在是很難看,我只是了解之后就沒仔細(xì)看了。
   我們剛剛分析出來Page中的ViewState反序列化之后是Triplet這個類型,實際上這個類在MSDN中就查得到,它就是一個包含了三個對象的對象,說簡單點,它就是一個能放三個箱子的大箱子(好像還是說的比較糊涂,呵呵),它有三個屬性:First、Second、Thrid :),分別代表三個對象。
   對應(yīng)到Page當(dāng)中,F(xiàn)irst是Page.GetTypeHashCode()的返回值,這個方法是System.Web.UI.Page定義的一個保護(hù)的虛擬方法,返回一個整型,由Aspx文件生成的類來實現(xiàn)的,因為這個類是有Asp.Net負(fù)責(zé)在運行期生成源代碼并編譯,它會計算出一個大常量作為返回值,這個返回值在整個Web應(yīng)用程序所有的Page中是唯一的。(提一句題外話,Asp.Net自動產(chǎn)生的源代碼可以到 系統(tǒng)盤:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\Temporary ASP.NET Files下面去找),這個唯一的Hash值是為了在ViewState中產(chǎn)生一個標(biāo)記,使這個ViewState只適用與對應(yīng)的頁面。
   Second則是通Control.SaveViewStateRecursive方法遞歸保存頁面控件樹的ViewState返回的對象,也就是真正的ViewState的數(shù)據(jù)。
   Third中保存的是當(dāng)前頁面需要PostBack的控件名的列表。
  
   分析了頁面的ViewState的構(gòu)成,我們再來看Control的ViewState的實現(xiàn)。ViewState是System.Web.UI.Control類實現(xiàn)的一個屬性,這個屬性的類型是System.Web.UI.StateBag,這個類就包含了ViewState數(shù)據(jù)結(jié)構(gòu)的實現(xiàn),實際上它的內(nèi)部也就是個Hash表,通過Key值來保存和檢索數(shù)據(jù)。
  那么服務(wù)器控件是怎么實現(xiàn)保存狀態(tài)的呢?
  我們知道,所有的服務(wù)器控件都是從System.Web.UI.Control派生的,所以都擁有ViewState這個屬性,在Control內(nèi)部,定義了兩個Protected的虛擬方法:
    protected virtual object SaveViewState()
  和
protected virtual void LoadViewState(object savedState)
  這兩個方法是給子控件派生用來保存和讀取自己的ViewState的,比如我們有一個自己寫的控件,往ViewState中保存了一個字符串,那么我們的方法大致像這樣:
    protected virtual object SaveViewState()
    {
       object[] states = new object[2];
       states[0] = base.SaveViewState();      //記得保存父控件的ViewState
       states[1] = "Hello,I'm timmy!";        //這里保存我們自己的
     
       return states; //返回重新包裝后的保存對象
    }
    獲取的時候:
    protected override void LoadViewState(object savedState)  //這里的savedState就是我們Save的時候return 的object數(shù)組
    {
       object[] states = (object[])savedState;
       base.LoadViewState( states[0] );   //把父類的數(shù)據(jù)給他自己去解析
       string myData = (string)states[1];  //獲取我們自己的數(shù)據(jù)
    }
   我們可以按照自己的方式來保存,不一定非要像上面這樣用數(shù)組,實際上我們可以用任何支持序列化的對象都可以,父類并不關(guān)心子類如何保存,我們只要在Save和Load的時候使用同樣的方式,并且把正確的數(shù)據(jù)傳遞給父類方法就可以了。
  
   另外,還有一個問題就是我們使用的Control的ViewState是Key-Value這樣的鍵值對,那它是怎么保存的呢?
   實際上很簡單,System.UI.Web下面有一個類叫Pair,呵呵,這個和Triplet差不多,只是它里面只有兩個對象。StateBag保存的時候,F(xiàn)irst會存放所有Key值的數(shù)組,Second則存放所有Value的數(shù)組。
   在Control內(nèi)部有兩個internal的方法:
   internal object SaveViewStateRecursive();
   internal void LoadRecursive();
   這兩個方法由System.Web.UI.Page來調(diào)用,Page在Render結(jié)束后就會調(diào)用SavePageViewState方法,SavePageViewState方法會調(diào)用Control的SaveViewStateRecursive()方法,這個方法就是通過遞歸調(diào)用每一個Control.Controls的SaveViewStateRecursive方法來保存控件樹中所有控件的ViewState。到這里,可能聰明的朋友要問了,既然SaveViewStateRecursive是遞歸調(diào)用保存的方法,那么我們上面寫的SaveViewState()方法又有什么用呢?
   我們知道,Control.Controls可能會有很多個,而且我們的SaveViewState()只保存了當(dāng)前控件的數(shù)據(jù),而沒有記錄控件樹的結(jié)構(gòu),那么如果我們遞歸SaveViewState()方法來保存數(shù)據(jù)的話,那么控件樹的結(jié)構(gòu)就會丟失,那么Load的時候就沒辦法還原了,實際上在SaveViewStateRecursive方法中大致的代碼是這樣:
    [1] 獲取控件自己的ViewState(調(diào)用SaveViewState方法)
    [2] 循環(huán)子控件
     {
         定義兩個動態(tài)數(shù)組,一個保存控件的索引,一個保存遞歸調(diào)用子控件SaveViewStateRecursive方法返回的值
     }
    [3] 定義一個Triplet(呵呵,這個東西又出現(xiàn)了)
    [4] First保存本控件的ViewState
    [5] Second保存子控件的索引
    [6] Third保存遞歸子控件SaveViewStateRecursive方法的返回值
    [7] 返回Triplet
   這樣就保存了整個控件樹的ViewState和控件樹的結(jié)構(gòu)

   到這里,ViewState的實現(xiàn)我們大致了解了一下,最后得出一些結(jié)論:
   1、ViewState是存放在客戶端,因此會減輕服務(wù)器的負(fù)擔(dān),是一種比較好的保存數(shù)據(jù)的方式。
   2、因為ViewState本身的限制,只能保存可以序列化的對象,而且最好不要放太多東西,能省則省,以免在減慢傳輸?shù)乃俣?,以及加重服?wù)器解析的負(fù)擔(dān)。
   3、我們通過很簡單的方式就可以把ViewState里面的值獲取出來,我們上面討論了一些,雖然沒有把解析的代碼寫出來,但是利用LosFormatter可以得到ViewState反序列化后的對象,那么要解析出來簡直是易如反掌;所以ViewState在安全性上面還是比較差,建議不要
存放比較機(jī)密和敏感的信息,盡管ViewState可以加密,但是由于ViewState要保存在客戶端,天生就有安全性的隱患。
   4、實際從技術(shù)角度,ViewState沒有任何新意,但是結(jié)合服務(wù)器控件的設(shè)計還是很巧妙的。
  
   最后,以我個人的觀點,我覺得ViewState的出現(xiàn)很大程度上減輕了程序員的負(fù)擔(dān),但是要看清的是ViewState的本質(zhì),合理的應(yīng)用它。
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
asp.net 同一個頁面中如何保持變量的值在多個事件中變換???
ASP.NET頁面間數(shù)據(jù)傳遞的方法講解|.net(C# vb asp)
Asp.net中的ViewState用法
Application、Cookie、Session和Cache
APPlication,Session,Cookie,ViewState和Cache之間的...
ViewState與Session
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服