日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ViewState机制由浅入深1

發布時間:2023/12/18 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ViewState机制由浅入深1 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1???????? ViewState機制是什么?

ViewState機制是asp.net中對同一個Page的多次請求(PostBack)之間維持Page及控件狀態的一種機制。在WebForm中每次請求完,Page對象都會被釋放,對同一個Page的多次請求之間的狀態信息,如何進行維護呢?WebForm中,每次請求都會存在客戶端和服務器之間的一個交互。如果請求完成之后將一些信息傳回到客戶端,下次請求的時候客戶端再將這些狀態信息提交給服務器,服務器端對這些信息使用和處理,再將這些信息傳回給客戶端。這樣是不是就可以對同一個Page的多次請求(PostBack)之間維持狀態了。對這就是ViewState的基本工作模式。ViewState的設計目的主要就是為了將必要的信息持久化在頁面中。這樣通過ViewState在頁面回傳的過程中保存狀態值,使原本沒有“記憶”的Http協議變得有“記憶”起來。

2???????? ViewState機制如何工作?

下面我們看看ViewState機制是如何具體的工作的。

2.1?客戶端:

我們先從客戶端看起,在客戶端的HTML源代碼中我們可以看到下面的代碼

<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE"

value="/wEPDwULLTE0MTAzNDUwNThkZKr77J2uy7fatyBou8PocG80X4Jt" />

這個就是ViewState在客戶端的保存形式,它保存在一個ID為__VIEWSTATE的Hidden中,它的Value是使用Base64編碼后的字符串。這個字符串實際上是一個對象(Pair類型)序列化之后的結果。這個對象保存了整個頁面的控件樹的ViewState。可以使用一些工具將這個字符串進行解碼查看其內容,比如ViewStateDecoder,ViewStateAnalyzer。

2.2?服務器端:

在服務器端和ViewState機制密切相關的有三個類Page,Control,StateBag。他們3者的關系如下圖所示:


圖1

Page繼承自Control,Control和StateBag是聚合關系,在Control中有一個StateBag的實例ViewState。這三個類互相協作完成ViewState機制的大概過程如下。Page對客戶端請求進行處理,在處理的過程中先是將客戶端提交的_VIEWSTATE反序列化為對象,調用Control的相關方法給所有的控件裝載數據,這些數據是上次請求結束后控件的狀態數據。在之后的一些事件中這些狀態數據可能被修改。在請求結束之前調用Control的相關方法得到所有控件的被修改過的狀態數據,之后Page將其進行序列化,并返回給客戶端。在Control中又具體調用StateBag類的方法完成狀態數據的加載和保存。

2.2.1?? Page中的處理


圖2 Page生命周期

1)???? InitRecursive

在Page的生命周期中有3處與ViewState相關,在初始化階段調用Control. InitRecursive,它遞歸對所有的控件進行初始化,其中調用了Control.TrackViewState。TrackViewState中打開跟蹤ViewState開關。

2)???? LoadAllState

在初始化完成之后會調用Page.LoadAllState,LoadAllState只有在PostBack的時候才會執行,它的主要功能是將從頁面傳遞來的__VIEWSTATE的值反序列化為Pair類型的對象,然后將這個對象中存儲的ViewState的值加載到Page及所有控件中。實際上LoadAllState加載了ControlState(控件狀態)及ViewState(視圖狀態),本文主要是討論ViewState,對ControlState部分的處理不進行描述。

LoadAllState中主要有兩步:Page.LoadPageStateFromPersistenceMedium和Control.LoadViewStateRecursive。

在LoadPageStateFromPersistenceMedium中發生了如下的調用層次

Page.LoadPageStateFromPersistenceMedium

è??? HiddenFieldPageStatePersister.Load

è??? ObjectStateFormatter.Deserialize

以上完成的功能是將客戶端提交的_VIEWSTATE反序列化為一個類型為Pair的對象pair。

Control.LoadViewStateRecursive中將遞歸加載控件的ViewState,具體在下面進行講解。

3)???? SaveAllState

SaveAllState它的操作和LoadAllState相反。SaveAllState中主要有兩步Control.SaveViewStateRecursive及Page SavePageStateToPersistenceMedium。

Control.SaveViewStateRecursive中將所有控件的ViewState屬性遞歸加載到一個Pair對象中,具體實現細節在下面講解。

Page SavePageStateToPersistenceMedium中發生如下的調用關系。

Page SavePageStateToPersistenceMedium

è??? HiddenFieldPageStatePersister.Save

è??? ObjectStateFormatter.Serialize

將Control.SaveViewStateRecursive生成的對象序列化為一個字符串,并賦值給Page.ClientState屬性。

在Render階段發生如下的調用關系:

HtmlForm.RenderChildren

è??? Page.BeginFormRender

è??? Page.RenderViewStateFields

最終將ClientState屬性中的值寫入到HTML頁面的_VIEWSTATE中。

在Control.InitRecursive中打開跟蹤開關,打算對ViewState的值進行跟蹤,在Page.LoadAllState中將客戶端提交的__VIEWSTATE的值裝載到各個控件的ViewState中,在Page.SaveAllState中將發生變化的ViewState序列化為一個字符串,在Render階段發送回客戶端。

4)???? ViewState序列化與反序列化

PageStatePersister 是一個抽象類,是表示將ViewState信息序列化及反序列化機制的基類。在Page.LoadPageStateFromPersistenceMedium中示意代碼如下:

protected internal virtual object LoadPageStateFromPersistenceMedium()

{

????????? PageStatePersister pageStatePersister = this.PageStatePersister;

????????? pageStatePersister.Load();

????????? return new Pair(pageStatePersister.ControlState, pageStatePersister.ViewState);

}

在Page.SavePageStateToPersistenceMedium中的示意代碼如下:

protected internal virtual void SavePageStateToPersistenceMedium(object state)

{

??? ??? PageStatePersister pageStatePersister = this.PageStatePersister;

??????? Pair pair = (Pair) state;

??????? pageStatePersister.ControlState = pair.First;

??????? pageStatePersister.ViewState = pair.Second;

??????? pageStatePersister.Save();

}

在Asp.net2.0中實現PageStatePersister這個抽象類,具體提供持久化機制的類是HiddenFieldPageStatePersister。它實現了Load和Save兩個方法,Load時將__VIEWSTATE反序列化為一個Pair對象,Save時將Pair對象序列化為一個字符串賦值給Page.ClientState。HiddenFieldPageStatePersister中采用的格式器是ObjectStateFormatter,其實現string Serialize(object state),和object Deserialize(string serializedState)這兩個方法,從而實現對Pair對象的序列化和反序列化。

public string Serialize(object state)中的示意代碼如下:

MemoryStream memoryStream = GetMemoryStream();

Serialize(memoryStream, state);

byte[] buf = memoryStream.GetBuffer();

if (RequiresViewStateEncryptionInternal)

{

?buf = MachineKeySection.EncryptOrDecryptData(true, buf, this.GetMacKeyModifier(), 0, length);

?length = buf.Length;

}

else if (EnableViewStateMac)

{

buf = MachineKeySection.GetEncodedData(buf, this.GetMacKeyModifier(), 0, ref length);

}

return Convert.ToBase64String(buf, 0, length);

將state序列化為內存流,在將其轉換為字節流。如果需要加密則對其進行加密處理,否則需要Mac則進行Mac處理。最后將字節流進行Base64編碼轉換為字符串。

public object Deserialize(string serializedState) 中的示意代碼如下:

byte[] buf = Convert.FromBase64String(serializedState);

int length = buf.Length;

if (ContainsEncryptedViewState)

{

buf = MachineKeySection.EncryptOrDecryptData(false, buf, this.GetMacKeyModifier(), 0, length);

?length = buf.Length;

}

else if (EnableViewStateMac)

{

buf = MachineKeySection.GetDecodedData(buf, this.GetMacKeyModifier(), 0, length, ref length);

}

MemoryStream memoryStream = GetMemoryStream();

memoryStream.Write(buf, 0, length);

return this.Deserialize(memoryStream);

將字符串進行Base64解碼為字節流,如果需要解密則進行解密處理,否則需要進行需要Mac則進行Mac處理,將字節流轉換為內存流,進行反序列化返回Pair對象。

轉載于:https://www.cnblogs.com/hobe/archive/2008/03/25/1122203.html

總結

以上是生活随笔為你收集整理的ViewState机制由浅入深1的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。