當前位置:編程學習大全網 - 源碼下載 - 如何使用IsPostBack和ViewState提高頁面效率?

如何使用IsPostBack和ViewState提高頁面效率?

1 IsPostBack簡介

IsPostBack是Page類的壹個bool屬性,用來判斷對當前表單的請求是否是第壹次。當IsPostBack=true時,表示不是第壹次。

請求,我們稱之為回發,意思是當IsPostBack=false時的第壹個請求。在ASP.NET框架內,有許多場景可以判斷IsPostBack,例如

LoadAllState等操作需要在回發中完成。我們在使用WebForm開發自己的時候經常會在Page_Load中判斷IsPostBack,因為

對於第壹個請求,將執行Page_Load,對於非第壹個請求,將執行Page_Load。為什麽同壹個表單會有多個請求?ASP.NET引入了服務。

服務器端事件,支持服務器端事件的控件,會對當前窗體進行請求,所以很多情況下我們需要區分是否是對該窗體的第壹次請求。

2 IsPostBack結論

我對源代碼中相關處理的分析。Net得出以下結論:

結論①對於使用Server.Transfer時遷移的頁面,IsPostBack=false。

結論② Post模式如果請求中沒有請求值,即請求。Form =null,IsPostBack = false;如果請求中沒有請求的值,即

請求。QueryString =null,IsPostBack=false。

結論(3)如果對QueryString或Form求值,則QueryString或Form中的鍵沒有“__VIEWSTATE”和“__EVENTTARGET”以及。

__VIEWSTATEFIELDCOUNT”,並且沒有鍵為null,值以“__VIEWSTATE”開頭,並且沒有值為“__EVENTTARGET”的鍵-值對,則IsPostBack

=假.

結論④當反應。重定向模式用於遷移到自圖,IsPostBack=false。

結論⑤發生交叉頁面回發。訪問PreviousPage屬性時,源頁的IsPostBack=true。

結論⑥跨頁提交時目標頁面為IsPostBack=false。

結論Server.Execute遷移的頁面的IsPostBack=false

結論在頁面運行過程中,相應的DLL已經更新,頁面的樹結構也發生了變化。在這種情況下,請求時IsPostBack=false。

這些結論可以這樣理解:壹般來說,如果請求中沒有請求值,IsPostBack=false。如果您要求評估,但不包括某些特殊功能,如“__VIEWSTATE”

特殊鍵或值,IsPostBack=false。Net framework會在每次請求後向客戶端返回壹些特殊的隱藏字段“__VIEWSTATE”)。有壹些特殊情況。

如果上述規則不能正確判斷,需要特殊處理,這些情況包括服務器。轉移,回應。重定向,交叉回發,服務器。執行並發送。

頁面元素被更改並重新編譯。

壹般來說,記住上面的結論就夠了。如果妳有興趣或者懷疑,請繼續看下面的IsPostBack推理過程。

3 IsPostBack推理過程

下面是分析IsPostBack是如何根據。Net框架。對於這些結論的推斷,我做過相關的實驗來證明推斷的正確性,因為

由於篇幅原因,這些測試代碼沒有反映出來。此外,也不可能反映。Net框架,只需列出相關的代碼片段,說明推斷的依據即可。

另外,由於本人水平有限,對代碼的理解還有壹些不足之處。Net框架。找到後請指正。謝謝妳。

publicbool是PostBack

{

得到

{

如果(這個。_requestValueCollection == null)

{

返回false

}

如果(這個。_isCrossPagePostBack)

{

返回true

}

if (this_pageFlags[8])

{

返回false

}

返回(

(這個。Context . ServerExecuteDepth & lt= 0) ||

((這個。上下文。處理程序!= null)& amp;& amp

(基礎。GetType() == this。Context.Handler.GetType()))

)& amp& amp!這個。_fPageLayoutChanged

);

}

}

我們把每壹個if判斷作為壹個小節,做如下分析。

3.1這個。_requestValueCollection == null

如果(這個。_requestValueCollection == null)

{

返回false

}

可以看出,當_requestValueCollection等於null時,IsPostBack等於false。

page.processrequestmain (bool,bool)中有以下代碼:

如果(這個。PageAdapter!=空)

{

這個。_requestValueCollection = this。page adapter . DeterminePostBackMode();

}

其他

{

這個。_requestValueCollection = this。DeterminePostBackMode();

}

頁面適配器。DeterminePostbackMode最後調用了Page.DeterminePostBackMode,我們來看看如何實現Page.DeterminePostBackMode。

受保護的內部虛擬名稱值集合DeterminePostBackMode()

{

如果(這個。請求==空)

{

返回null

}

如果(這個。Context.PreventPostback)

{

返回null

}

namevaluecollectioncollectionbasedonmethod = this。GetCollectionBasedOnMethod(false);

if(collectionBasedOnMethod = = null)

{

返回null

}

bool flag = false

string[]values = collectionBasedOnMethod。get values((string)null);

如果(值!=空)

{

int length =值。長度;

for(int I = 0;我& lt長度;i++)

{

if(值[i]。StartsWith("__VIEWSTATE ",StringComparison。序數)||

(values[i] == "__EVENTTARGET "))

{

flag = true

打破;

}

}

}

if((collectionBasedOnMethod[" _ _ VIEWSTATE "]= = null)& amp;& amp(collectionBasedOnMethod[" _ _ VIEWSTATEFIELDCOUNT "]= = null))& amp;& amp

((collectionBasedOnMethod[" _ _ event target "]= = null)& amp;& amp!旗幟))

{

返回null

}

如果(這個。request . querystringtext . index of(

HttpResponse。RedirectQueryStringAssignment,StringComparison。序數)!= -1)

{

collectionBasedOnMethod = null

}

返回collectionBasedOnMethod

}

該函數返回null意味著IsPostBack=false。對上述函數中每壹個返回null的地方做如下分析。

3.1.1這個。上下文。請求==空

如果(這個。context . Request = = null){ return null;}這個。Context.Request == null只應在異常情況下發生。

正常情況下,HttpContext和HttpRequest對象會在httpruntime . processrequestinternal中創建。

3.1.2這個。Context.PreventPostback

如果(這個。Context.PreventPostback) {返回null} PreventPostback將在HttpServerUtility中使用。轉移,及其產生

代碼如下:

公共void傳輸(字符串路徑)

{

bool preventPostback = this。_上下文。PreventPostback

這個。_上下文。PreventPostback = true

這個。轉移(路徑,真);

這個。_上下文。PreventPostback = PreventPostback;

}

設置上下文。調用服務器時preventpostback = ture。屏幕遷移轉移。這裏的結論是①:對於帶服務器的遷移。轉移,移動到。

IsPostBack=false的頁面。

3.1.3 collectionBasedOnMethod = = null

namevaluecollectioncollectionbasedonmethod = this。GetCollectionBasedOnMethod(false);

if(collectionBasedOnMethod = = null)

{

返回null

}

呼叫頁面後。getCollectionBasedonMethod,判斷其返回值。如果其返回值為null,則IsPostBack為false。

頁面。getCollectionBasedonMethod定義如下:

內部名稱值集合GetCollectionBasedOnMethod(bool dontreturnull)

{

如果(這個。_請求。HttpVerb == HttpVerb。帖子)

{

如果(!dontReturnNull & amp& amp!這個。_請求。HasForm)

{

返回null

}

歸還這個。_請求。形式;

}

如果(!dontReturnNull & amp& amp!這個。_請求。HasQueryString)

{

返回null

}

歸還這個。_請求。QueryString

}

從上面的代碼可以看出,返回值是null _ request.hasform = null或者_ request.hasquerystring = null。這裏得出結論②:如果使用②:Post模式,

請求中沒有請求的值,即request。Form =null,IsPostBack = false;如果請求中沒有請求值,即Request,則獲取方法。QueryString =null,那麽

IsPostBack=false .

3.1.4((collectionBasedOnMethod[" _ _ VIEWSTATE "]= = null)& amp;& amp(collectionBasedOnMethod[" _ _ VIEWSTATEFIELDCOUNT "]= = null))& amp;& amp

((collectionBasedOnMethod[" _ _ event target "]= = null)& amp;& amp!旗幟)

bool flag = false

string[]values = collectionBasedOnMethod。get values((string)null);

如果(值!=空)

{

int length =值。長度;

for(int I = 0;我& lt長度;i++)

{

if(值[i]。StartsWith("__VIEWSTATE ",StringComparison。序數)||

(values[i] == "__EVENTTARGET "))

{

flag = true

打破;

}

}

}

上面這段代碼的意思是判斷請求的鍵-值對中是否沒有鍵,其值是以“__VIEWSTATE”開頭還是為“__EVENTTARGET”。例如,下面的Get請求

方法將使flag=true。

…/default . aspx?_ _視圖狀態

…/default . aspx?__EVENTTARGET

為獲取模式"?__VIEWSTATE = "以__VIEWSTATE作為請求的鍵,其值為" ",但"?__VIEWSTATE”將認為其鍵為“null ”,其值為。

" _ _視圖狀態"

如果(

((collectionBasedOnMethod[" _ _ VIEWSTATE "]= = null)& amp;& amp(collectionBasedOnMethod[" _ _ VIEWSTATEFIELDCOUNT "]= = null))& amp;& amp

((collectionBasedOnMethod[" _ _ event target "]= = null)& amp;& amp!旗幟))

{

返回null

}

上述條件意味著所請求的鍵中沒有“__VIEWSTATE”、“__EVENTTARGET”和“__VIEWSTATEFIELDCOUNT”,如果標誌為false,將返回null。

false標誌意味著沒有鍵為null,值以“__VIEWSTATE”開頭,並且沒有值為“__EVENTTARGET”的鍵-值對。

這裏得出結論③如果對QueryString或Form求值,QueryString或Form中的鍵沒有“__VIEWSTATE”和“__EVENTTARGET”以及。

__VIEWSTATEFIELDCOUNT”,並且不存在鍵為null且值以“__VIEWSTATE”開頭且值為“__EVENTTARGET”的鍵-值對,則IsPostBack= =

錯誤.

3.1.5這個。request . querystringtext . index of(http response。RedirectQueryStringAssignment,StringComparison。序數)!= -1

如果(這個。request . querystringtext . index of(http response。RedirectQueryStringAssignment,StringComparison。序數)!= -1)

{

collectionBasedOnMethod = null

}

httpresponse的值。RedirectQueryStringAssignment為“_ _ redir = 1”,這意味著如果QueryStringText包含“_ _ redir = 1”。

則返回null。會在HttpRequest中判斷。重定向到如果IsPostBack為true,並且URL不包含“_ _ redir = 1”,則將“_ _ redir = 1”添加到URL中。

"。壹般來說,我們根據請求遷移到的頁面。重定向應該是IsPostBack=false。有壹種特殊情況,我們用request.redirect遷移到當前頁面。

Page,並且IsPostBack為true。發生這種情況時,請在request.Redirect中的URL中添加“__redir=1+0”。ProcessRequestMain,它將重新執行

IsPostBack被判斷為fales。

這裏的結論是當反應。重定向模式用於遷移到自圖,IsPostBack=false。

此時,您可能會奇怪,為什麽在使用Response時需要特殊處理。重定向至“遷移至您自己的屏幕,以及為什麽不使用響應”診斷樹。重定向至“遷移至其它屏幕”。

使用Response時。重定向至“遷移至其它映像,響應”。Form=null和響應。QueryString=null,所以可以判斷IsPostBack=false。但是使用

當回應。重定向模式遷移到自拍,響應。查詢字符串

3.2這個。_isCrossPagePostBack

如果(這個。_isCrossPagePostBack)

{

返回true

}

_ iscrossPagepostback將在頁面的PreviousPage屬性中設置,具體代碼如下:

公共頁面上壹頁

{

得到

{

ITypedWebObjectFactory vPathBuildResult =(ITypedWebObjectFactory)build manager。GetVPathBuildResult(this。語境,

這個。_ previous page path);

if(類型of(第頁))。IsAssignableFrom(vPathBuildResult。實例化類型))

{

這個。_ previous Page =(Page)vPathBuildResult。create instance();

這個。_上壹頁。_ isCrossPagePostBack = true

這個。Server.Execute(this。_previousPage,TextWriter。Null、true、false);

}

}

歸還這個。_ previousPage

}

}

當跨頁提交發生時,在訪問PreviousPage屬性時,源頁的IsCrossPagePostBack將被設置為true。這裏得出的結論是(5)跨頁提交發生。

(CrossPagePostBack),當訪問PreviousPage屬性時,源頁的IsPostBack=true。

3.3這個。_pageFlags[8]

如果(這個。_pageFlags[8])

{

返回false

}

在第頁。ProcessRequestMain,下面有壹段代碼要給_pageFlags[8]賦值。

else if(!這個。IsCrossPagePostBack)

{

VirtualPath path = null

如果(這個。_ requestValueCollection[" _ _ previous page "]!=空)

{

嘗試

{

path = VirtualPath。CreateNonRelativeAllowNull(

DecryptString(this。_ requestValueCollection[" _ _ previous page "]);

}

catch(密碼異常)

{

這個。_ page flags[8]= true;

}

如果((路徑!= null)& amp;& amp(路徑!=這個。request . CurrentExecutionFilePathObject))

{

這個。_ page flags[8]= true;

這個。_ previousPagePath = path

}

}

}

_pageFlags[8]在解密出現異常時為真,這種情況發生的可能性較小。我們先忽略它,專註於另壹種情況,結合這種情況的所有條件。

IsCrossPagePostBack = false & amp& amp_ requestValueCollection[" _ _ previous page "]!= null & amp& amp路徑!= null & amp& amp(路徑!=

這個。request . CurrentExecutionFilePathObject).當發生跨頁提交時,目標頁的IsCrossPagePostBack=false。這時,源頁面

將“__PREVIOUSPAGE”等信息提交到目標頁面,so _ RequestValueCollection[" _ _ previous page "]!= null .當前請求的

CurrentExecutionFilePathObject是根據目標頁面的路徑生成的,與使用_ RequestValueCollection[" _ _ Previous Page "]生成的path對象不同。

這裏得出結論,跨頁提交時目標頁面為IsPostBack=false。為什麽需要對CrossPagePostBack的目標頁面這樣做?

那處理呢?當CrossPagePostBack發生時,源頁面的信息將被提交到目標頁面。此時,請求。形式!= =null,並根據其他規則包含__VIEWSTATE和其他鍵。

會被判斷為IsPostBack=true,所以需要對CrossPagePostBack的目標頁面進行特殊判斷。

3.4(這個。Context . ServerExecuteDepth & lt= 0) ||((這個。上下文。處理程序!= null)& amp;& amp(基礎。GetType() ==

這個。Context.Handler.GetType()))

在HttpServerUtility中,有下面的代碼來操作上下文。ServerExecuteDepth。

public void Execute(字符串路徑、TextWriter編寫器、bool preserveForm)

{

嘗試

{

這個。_上下文。server execute depth++;

handler = this。_上下文。application instance . MapHttpHandler(this。_context,請求。請求類型,路徑3,文件名,

useAppConfig);

}

最後

{

這個。_上下文。server execute depth-;

}

}

對於上下文也有類似的操作。http serverutility中的ServerExecuteDepth。執行內部。HttpServerUtility。執行呼叫。

HttpServerUtility。執行內部.從這個上下文可以看出。ServerExecuteDepth表示Server.Execute. In調用中的執行深度

語境。ServerExecuteDepth >當服務器。執行>;0。另外,調用服務器後。執行,原始頁面對象仍然存儲在上下文中。手柄,也就是,

基地。GetType()!=這個。Context.Handler.GetType().所以對於服務器來說。Execute,this . context . server execute depth

((這個。上下文。處理程序!= null)此條件為假。這裏的結論是,使用Server.Execute遷移的頁面的IsPostBack=false

問題,為什麽需要對服務器進行特殊的判斷。執行?原因是在使用服務器時。執行,源頁面中的隱藏字段將被提交,此時,請求。形式!=空

而包含__VIEWSTATE的鍵會根據其他規則判斷為IsPostBack=true。

3.5這個。_fPageLayoutChanged

FPageLayoutChanged從這個變量的字面意思來看,頁面的布局發生了變化。

頁面中的代碼段。勞達爾州如下:

私有void LoadAllState()

{

string s = (string)秒。第壹;

整數=整數。解析(s,NumberFormatInfo。invariant info);

這個。_fPageLayoutChanged = num!=這個。gettype hashcode();

}

意味著當獲取的HashCode與ViewState中存儲的HashCode不壹致時,fPageLayoutChanged=true。GetTypeHashCode()返回壹個HashCode。

而且這個方法是在編譯aspx的時候生成的,只有當頁面上的元素發生變化時,返回值才會發生變化。這裏的結論是它運行在第頁。

在此期間,其對應的DLL已經更新,Page的樹形結構也發生了變化。在這種情況下,請求時IsPostBack=false。是確定當前頁面在您提交後是否被服務器返回。

當您直接在URL中輸入壹個頁面地址來訪問該頁面時。

此時,在服務器端創建的page對象的IsPostBack屬性為false。

當您提交此頁面時。

會將頁面控件中的壹些值和東西發送回服務器

然後服務器創建壹個新的頁面對象。

並讀取從ViewState返回給服務器的信息。

這個新page對象的IsPostBack屬性為true。

我突然想到

如果妳知道壹個頁面對象的生命周期,就很容易理解了。

可以查壹下相關資料。

知道每個頁面事件何時被觸發。

以及不同時期完成了哪些工作。

例如何時讀取視圖狀態。

何時執行控制事件

何時保存視圖狀態?

何時呈現頁面(即,將頁面發送給客戶端)

這個說起來比較麻煩> _ & lt

自己試試~ ~

如果妳明白這壹點

然後對ASP.NET·佩奇的回歸機制有壹個大致的了解。

這對以後解決壹些問題也會很有幫助

  • 上一篇:什麽叫摩爾定律?
  • 下一篇:花瓣遊泳是什麽軟件?
  • copyright 2024編程學習大全網