欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

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

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

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久