一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Asp.net2.0頁(yè)面執(zhí)行順序

 我的陽(yáng)光書(shū)吧 2012-03-17

Asp.net2.0頁(yè)面執(zhí)行順序

Asp.net2.0頁(yè)面執(zhí)行順序
2008-09-12 09:16

Asp.net是微軟.Net戰(zhàn)略的一個(gè)組成部分。它相對(duì)以前的Asp有了很大的發(fā)展,引入了許多的新機(jī)制。本文就Asp.net頁(yè)面的生命周期向大家做一個(gè)初步的介紹,以期能起到指導(dǎo)大家更好、更靈活地操縱Asp.net的作用。
當(dāng)一個(gè)獲取網(wǎng)頁(yè)的請(qǐng)求(可能是通過(guò)用戶提交完成的,也可能是通過(guò)超鏈接完成的)被發(fā)送到Web服務(wù)器后,這個(gè)頁(yè)面就會(huì)接著運(yùn)行從創(chuàng)建到處理完成的一系列事件。在我們?cè)噲D建立Asp.net頁(yè)面的時(shí)候,這個(gè)執(zhí)行周期是不必去考慮的,那樣只會(huì)自討苦吃。然而,如果被正確的操縱,一個(gè)頁(yè)面的執(zhí)行周期將是一道有效而且功能強(qiáng)大的工具。許多開(kāi)發(fā)者在編寫Asp.net的頁(yè)面以及用戶控件的時(shí)候發(fā)現(xiàn),如果知道整個(gè)過(guò)程中發(fā)生了什么以及在什么時(shí)候發(fā)生將對(duì)完成整個(gè)任務(wù)起到很重要的幫助作用。下面我就向大家介紹一下一個(gè)Asp.net頁(yè)面從創(chuàng)建到處理完成過(guò)程中的十個(gè)事件。同時(shí),也向大家展示如何在這些事件中添加自己的代碼以達(dá)到預(yù)定的效果。
一.初始化對(duì)象
一個(gè)頁(yè)面的控件(以及頁(yè)面本身)最初應(yīng)被正確的初始化。通過(guò)在你的C#文件的構(gòu)造函數(shù)中聲名所有對(duì)象(如圖1),頁(yè)面就知道要?jiǎng)?chuàng)建多少對(duì)象以及它們的類型。一旦你在你的構(gòu)造函數(shù)中聲名了所有的對(duì)象,你就可以通過(guò)繼承類、方法、事件或是屬性訪問(wèn)它們。然而,如果你的一些對(duì)象是在Aspx文件中指定的一些控件,那么這些控件就沒(méi)有屬性可言了。同時(shí),通過(guò)代碼訪問(wèn)它們會(huì)產(chǎn)生一些意外的錯(cuò)誤,因?yàn)檫@些控件實(shí)例是沒(méi)有一個(gè)確定的創(chuàng)建順序的(如果它們是被一起創(chuàng)建的)。還有,你可以通過(guò)OnInit來(lái)重載初始化事件,圖示如下(圖1):

圖1

二.導(dǎo)入Viewstate數(shù)據(jù)
在初始化事件后,所有控件只可以通過(guò)它們的ID被引用訪問(wèn)(因?yàn)檫€沒(méi)有相應(yīng)的DOM可使用)。在LoadViewState這個(gè)事件中,所有的控件將獲得它們的第一個(gè)屬性:Viewstate屬性。這個(gè)屬性最終將被返回給服務(wù)器以判斷這個(gè)頁(yè)面是已經(jīng)被用戶訪問(wèn)完畢還是仍然在被用戶所訪問(wèn)。Viewstate屬性以“名稱/值”對(duì)的字符串方式被保存,它包含了控件的文本以及值等信息。該屬性被存儲(chǔ)在一個(gè)隱藏的<input>控件的值屬性里,在請(qǐng)求頁(yè)面時(shí)被傳遞。這種方式比起Asp3.0的維持、判斷頁(yè)面狀態(tài)的方式有了很大的進(jìn)步啊。還有,你可以重載LoadViewState事件函數(shù)來(lái)對(duì)相應(yīng)的控件進(jìn)行值設(shè)定。下圖(圖2)是一個(gè)例子:

圖2

三.用LoadPostData處理Postback數(shù)據(jù)
在頁(yè)面創(chuàng)建的這個(gè)階段,服務(wù)器對(duì)頁(yè)面上的控件提交的表單數(shù)據(jù)(在Asp.net中稱postback數(shù)據(jù))進(jìn)行處理。當(dāng)一個(gè)頁(yè)面提交一個(gè)表單時(shí),框架就在每個(gè)提交了數(shù)據(jù)的控件上執(zhí)行一個(gè)IPostBackDataHandler接口操作。然后頁(yè)面執(zhí)行LoadPostData事件,解析頁(yè)面,找到每個(gè)執(zhí)行了IpostBackDataHandler接口操作的控件,并用恰當(dāng)?shù)膒ostback數(shù)據(jù)更新這些控件狀態(tài)。Asp.net是通過(guò)用NameValue集中的“名稱/值”對(duì)和每個(gè)控件的唯一的ID匹配來(lái)實(shí)現(xiàn)這一操作的。所以,在Asp.net的頁(yè)面上每個(gè)控件必須有一個(gè)唯一的ID,不可以出現(xiàn)幾個(gè)控件共有ID的情況。即使是用戶自定義的一些控件,框架也會(huì)賦予它們各自唯一的ID的。在LoadPostData事件后,就要執(zhí)行下面的RaisePostDataChanged事件了。
四.導(dǎo)入對(duì)象
在Load事件中,對(duì)象都實(shí)例化了。所有的對(duì)象第一次被布置在DOM頁(yè)面(在Asp.net中稱控件樹(shù))里了并且可以通過(guò)代碼或是相關(guān)的位置被引用。這樣,對(duì)象就可以很容易的從客戶端獲得諸如寬度、高度、值、可見(jiàn)性等在Html中的屬性值。在Load事件中,當(dāng)然還有像設(shè)置控件屬性等操作的發(fā)生。這個(gè)過(guò)程是整個(gè)生命周期中最重要、最主要的,你可以通過(guò)調(diào)用OnLoad來(lái)重載Load事件,圖示如下(圖3):

圖3

五.RaisePostBackChanged事件
就像在上面提到的那樣,這個(gè)事件是發(fā)生在所有的控件執(zhí)行了IPostBackDataHandler接口操作并被正確的postback數(shù)據(jù)更新后的。在這個(gè)過(guò)程中,每個(gè)控件都被賦予一個(gè)布爾值來(lái)標(biāo)志該控件有沒(méi)有被更新。然后,Asp.net就在整個(gè)頁(yè)面上尋找任何已被更新過(guò)的控件并執(zhí)行RaisePostDataChanged事件操作。不過(guò),這個(gè)事件是要在所有的控件都被更新了以及Load事件完成后才進(jìn)行的。這樣就保證了一個(gè)控件在被postback數(shù)據(jù)更新前,別的控件在RaisePostDataChanged事件中是不會(huì)被手動(dòng)改變的。
六.處理客戶端PostBack事件
當(dāng)由postback數(shù)據(jù)在服務(wù)器端引起的事件都完成后,產(chǎn)生postback數(shù)據(jù)的對(duì)象就執(zhí)行RaisePostBackEvent事件操作??墒菚?huì)有這種情況,由于一個(gè)控件狀態(tài)的改變使得它將表單返回給服務(wù)器或是用戶點(diǎn)擊了提交按鈕使得表單返回給服務(wù)器。在這種情況下應(yīng)該有相應(yīng)的處理代碼來(lái)體現(xiàn)事件驅(qū)動(dòng)這一面向?qū)ο螅∣OP)編程原則。由于要滿足呈現(xiàn)給瀏覽器的數(shù)據(jù)的精確性要求,在一系列postback事件中RaisePostBackEvent事件是最后發(fā)生的。
在postback過(guò)程中改變的控件不應(yīng)在執(zhí)行功能函數(shù)被調(diào)用后更新。也就是說(shuō),任何由于一個(gè)預(yù)期的事件而改變的數(shù)據(jù)應(yīng)該在最終的頁(yè)面上被反映出來(lái)。你可以通過(guò)修改RaisePostBackEvent函數(shù)來(lái)滿足你的要求,圖示如下(圖4):

圖4

七.預(yù)先呈遞對(duì)象
可以改變對(duì)象并將改變保存的最后時(shí)刻就是這一步――預(yù)先呈遞對(duì)象。這樣,你可以在這一步對(duì)控件的屬性、控件樹(shù)結(jié)構(gòu)等作出最后的修改。同時(shí)還不用考慮Asp.net對(duì)其作出任何改變,因?yàn)榇藭r(shí)已經(jīng)脫離了數(shù)據(jù)庫(kù)調(diào)用以及viewstate更新了。在這一步之后,對(duì)對(duì)象的所有修改將最終被確定,不能被保存到頁(yè)面的viewstate中了。你可以通過(guò)OnPreRender來(lái)重載這一步。
八.保存ViewState
所有對(duì)頁(yè)面控件的修改完成后viewstate就被保存了。對(duì)像的狀態(tài)數(shù)據(jù)還是保留在隱藏的<input>控件里面,呈現(xiàn)給Html的對(duì)象狀態(tài)數(shù)據(jù)也是從這里取得的。在SaveViewState事件中,其值能被保存到viewstate對(duì)象,然而這時(shí)在頁(yè)面上控件的修改卻不能了。你可以用SaveViewState來(lái)重載這一步,圖示如下(圖5):

圖5

九.呈遞給Html
運(yùn)用Html創(chuàng)建給瀏覽器輸出的頁(yè)面的時(shí)候Render事件就發(fā)生了。在Render事件過(guò)程中,頁(yè)面調(diào)用其中的對(duì)象將它們呈遞給Html。然后,頁(yè)面就可以以Html的形式被用戶的瀏覽器訪問(wèn)了。當(dāng)Render事件被重載時(shí),開(kāi)發(fā)者可以編寫自定義的Html代碼使得原先生成的Html都無(wú)效而按照新的Html來(lái)組織頁(yè)面。Render方法將一個(gè)HtmlTextWriter對(duì)象作為參數(shù)并用它將Html在瀏覽器上以網(wǎng)頁(yè)的形式顯示。這時(shí)仍然可以做一些修改動(dòng)作,不過(guò)它們只是客戶端的一些變化而已了。你可以重載Render事件,圖示如下(圖6):

圖6

十.銷毀對(duì)象
在呈遞給Html完成后,所有的對(duì)象都應(yīng)被銷毀。在Dispose事件中,你應(yīng)該銷毀所有在建立這個(gè)頁(yè)面時(shí)創(chuàng)建的對(duì)象。這時(shí),所有的處理已經(jīng)完畢,所以銷毀任何剩下的對(duì)象都是不會(huì)產(chǎn)生錯(cuò)誤的,包括頁(yè)面對(duì)象。你可以重載Dispose事件,見(jiàn)圖6。
全文總結(jié)
以上就是Asp.net頁(yè)面生命周期中的十個(gè)事件。每次我們請(qǐng)求一個(gè)Asp.net頁(yè)面時(shí),我們都經(jīng)歷著同樣的過(guò)程:從初始化對(duì)象到銷毀對(duì)象。通過(guò)了解Asp.net頁(yè)面的內(nèi)部運(yùn)行機(jī)制,我相信大家在編寫、調(diào)試代碼的時(shí)候會(huì)更加游刃有余的。
http://www./htm/center/prog/02_3_12_2.asp

 

 

今天碰到一個(gè)問(wèn)題,在MasterPage的OnLoad中加入一個(gè)判斷,希望在ContentPage的OnLoad之前執(zhí)行,結(jié)果發(fā)現(xiàn) MasterPage的Onload在ContentPage的OnLoad后執(zhí)行,后來(lái)把這個(gè)判斷移動(dòng)到MasterPage的OnInit中搞定

在一個(gè)單獨(dú)的頁(yè)面中,執(zhí)行順序?yàn)?/P>

  1. PreInit
  2. Init
  3. InitComplete
  4. PreLoad
  5. Load
  6. LoadComplete
  7. PreRender
  8. PreRenderComplete

在頁(yè)面有MasterPage的時(shí)候

  1. ContentPage.PreInit
  2. Master.Init
  3. ContentPage.Init
  4. ContentPage.InitComplete
  5. ContentPage.PreLoad
  6. ContentPage.Load
  7. Master.Load
  8. ContentPage.LoadComplete
  9. ContentPage.PreRender
  10. Master.PreRender

注意上面高亮的部分,除此之外其他的地方一般是先MasterPage后ContentPage,這里恰恰相反

那么控件的加載和頁(yè)面的幾個(gè)事件的關(guān)系是什么呢?

一般情況下,頁(yè)面中的控件回先于OnInit執(zhí)行,亦即

  1. Master中控件的Init
  2. ContentPage中控件的Init
  3. Master.Init
  4. Content.Init
  5. Content.Load
  6. Master.Load
  7. Master.中用戶控件load
  8. ContentPage頁(yè)面中的用戶控件的 page_load

可以看到控件的Init在Page的Init前執(zhí)行,所以在Init中我們就可以放心使用頁(yè)面中的控件了,但是下面的情況不同

如果你的頁(yè)面中使用WebControl,或者從WebControl繼承的控件,WebControl需要使用 CreateChildControls()來(lái)加載子控件,這個(gè)函數(shù)會(huì)在這個(gè)控件的Init后被調(diào)用,也就是說(shuō)在一個(gè)WebControl的OnInit 中,是沒(méi)有辦法直接使用其中的控件的,不過(guò)我們也可以自己用FindControl把控件加載進(jìn)來(lái),WebControl的其他方法的加載順序見(jiàn)下表

Event Description
Init You can use the OnInit method to trap this event and initialize member variables and other values.
LoadViewState You can trap this event to customize how the control retrieves information from the ASP.NET hidden ViewState field.
Load This event is raised after you create and initialize the control. This is the best place to make the connection to the database or load document content. You can trap the Load event by adding the OnLoad method to the class.
PreRender This event is raised before ASP.NET renders the control. Any changes to the control's state are saved into the hidden ViewState field.
SaveViewState This event is raised before the control state is persisted into the hidden ViewState field. You can trap the event to customize how this information is stored.
Render You can use the Render method to respond to this event and specify the HTML code that represents the component's content.
Dispose This event is useful for cleanup operations. It's raised before the control is torn down and is the best place to free the resources created during the load phase.
Unload This event is raised before the control is torn down. The official documentation says not to use this event to perform cleanup, and to rely on the Dispose event instead.

2)ASP.NET頁(yè)面生命周期描述

在以前寫個(gè)一篇關(guān)于ASP.NET頁(yè)面生命周期的草稿,最近又看了看ASP.NET,做個(gè)補(bǔ)充,看看頁(yè)面初始過(guò)程到底是怎么樣的
下面是ASP.NET頁(yè)面初始的過(guò)程:
1. Page_Init();
2. Load ViewState;
3. Load Postback data;
4. Page_Load();
5. Handle control events;
6. Page_PreRender();
7. Page_Render();
8. Unload event;
9. Dispose method called;

下面對(duì)其中的一些過(guò)程作下描述:
1. Page_Init();
這個(gè)過(guò)程主要是初始化控件,每次頁(yè)面載入執(zhí)行這個(gè)初始過(guò)程,包括第一次和以后的Postback(這里說(shuō)下Postback,其實(shí)就可以簡(jiǎn)單理解成用戶點(diǎn)
擊SUBMIT按鈕之類的,把表單<Form>提交給服務(wù)器,這就是一次postback),在這里面可以訪問(wèn)控件,但是這里面的控件值不是我們期待的控件里面的值,他只是一個(gè)控件的初始值(默認(rèn)值),舉例: 比如一個(gè)TextBox1,我們填入了"哈哈",在點(diǎn)擊SUBMIT提交了頁(yè)面后,在Page_Init()里面,我們?cè)L問(wèn)到的TextBox1.Text不是我們的"哈哈",而是開(kāi)始的""空字符串,如果TextBox1在我們?cè)O(shè)計(jì)的時(shí)候提供了默認(rèn)值,這里訪問(wèn)到的也就是提供的默認(rèn)值,為什么呢,這就要看下一個(gè)過(guò)程了.

對(duì)應(yīng)的事件Page.Init

2. Load ViewState
這個(gè)過(guò)程是載入VIEWSTATE和Postback數(shù)據(jù),比如我們上面的TextBox1,這時(shí)就賦了"哈哈",所以,在Post_Init()對(duì)控件賦值是無(wú)意義的,它都會(huì)
在這個(gè)過(guò)程里被改寫,當(dāng)然第一次頁(yè)面載入例外,因?yàn)闆](méi)有VIEWSTATE數(shù)據(jù)。

沒(méi)有對(duì)應(yīng)的事件

3.Load Postback data;
上面說(shuō)了,Postback可以理解成用戶提交表單數(shù)據(jù),所以這里就是處理表單數(shù)據(jù),當(dāng)然這里要設(shè)計(jì)到控件的設(shè)計(jì),一般情況不會(huì)要我們自己處理這
個(gè)過(guò)程,我們暫且略過(guò). (在以前那篇關(guān)于ASP.NET頁(yè)面生命周期的簡(jiǎn)單描述中,把這個(gè)過(guò)程和Load ViewState放在了一起,其實(shí)那是微軟提供的生命周期過(guò)程,這里單獨(dú)提出來(lái)是為了讓大家明白這是一個(gè)單獨(dú)的過(guò)程)

沒(méi)有對(duì)應(yīng)的事件
4. Page_Load();
這個(gè)過(guò)程也是每次頁(yè)面載入時(shí)一定會(huì)執(zhí)行的,但是注意和Page_Init的區(qū)別,上面已經(jīng)涉及了,這里注意的是一般都會(huì)用到Page.IsPostBack,該
值指示該頁(yè)是否正為響應(yīng)客戶端回發(fā)而加載,或者它是否正被首次加載和訪問(wèn)。
private void Page_Load(object sender, System.EventArgs e)
{
if(!Page.IsPostBack)
{
   //第一次執(zhí)行的CODE HERE
}
else
{
    //用戶提交FORM(即Postback)CODE HERE
}

//每次這里的都回執(zhí)行CODE HERE
}

對(duì)應(yīng)的事件Page.Load

5. Handle control events;
這個(gè)過(guò)程里,相應(yīng)具體的控件事件,比如private void ListBox1_SelectedIndexChanged(object sender, System.EventArgs e)事件等等

沒(méi)有對(duì)應(yīng)的事件(我們自己的事件函數(shù)都包括在這個(gè)過(guò)程里比如上面的ListBox1_SelectedIndexChanged)

6. Page_
預(yù)先呈遞對(duì)象,這里是在向用戶程序呈現(xiàn)數(shù)據(jù)的倒數(shù)第二步,我估計(jì)提供這個(gè)過(guò)程的意義,也就是在這里能對(duì)控件屬性等等要呈現(xiàn)給用戶的數(shù)據(jù)進(jìn)
行修改,這也是最后的修改,以前的修改(比如在Page_Init里面)都可能被覆蓋.做完這了還會(huì)進(jìn)行一個(gè)操作就是保存狀態(tài),即SaveViewState.

對(duì)應(yīng)的事件時(shí)Page.PreRender

7. Page_Render();
大家可以在瀏纜器里View->Source查看到,每個(gè)頁(yè)面都有一個(gè)隱藏的<input>,這里面的"__VIEWSTATE"就是我們服務(wù)器寫回來(lái)的頁(yè)面狀態(tài)信息,
在 這個(gè)之前,服務(wù)器要呈現(xiàn)頁(yè)面(也就是構(gòu)造HTML格式的文件),就是從這個(gè)"__VIEWSTATE"里面獲取的數(shù)據(jù),當(dāng)然大家也注意到了,這里有個(gè) Page.Render事件,我們可以添加自己的處理代碼,也就是說(shuō)我們又可以更改數(shù)據(jù),不過(guò)這里推薦不要在這里修改,既然提供了PreRender,就 應(yīng)該在里面做最后的修改,當(dāng)然這不是必須的,只是推薦!

對(duì)應(yīng)的事件Page.Render

8. Unload event;
大家應(yīng)該明白,當(dāng)想服務(wù)器請(qǐng)求一個(gè)對(duì)象的時(shí)候,就會(huì)在內(nèi)存里生成一個(gè)繼承頁(yè)面對(duì)象,也就是頁(yè)面的類,它繼承自System.Web.UI.Page.
當(dāng)頁(yè)面對(duì)象從內(nèi)存中卸載時(shí)發(fā)生,將觸發(fā)該事件.

對(duì)應(yīng)的事件Page.Unload

9. Dispose method called;
銷毀所有的對(duì)象.當(dāng)從內(nèi)存釋放Page時(shí)發(fā)生,這是生存期的最后階段??赡艿?和9似乎有些模糊,不過(guò)我也沒(méi)怎么搞清楚,待研究!

對(duì)應(yīng)的事件Dispose

以上就是ASP.NET頁(yè)面周期的描述。

注意上面灰色背景的文字,如果一個(gè)過(guò)程中有對(duì)應(yīng)的事件,我們可以自己定義一個(gè)函數(shù)(當(dāng)然先在MSDN中找到函數(shù)原型),然后在
InitializeComponent中向事件的鏈表上添加上去,像下面:
private void InitializeComponent()
{   
this.Unload += new System.EventHandler(this.MainWebForm_Unload);
this.Load += new System.EventHandler(this.Page_Load);
this.Init += new System.EventHandler(this.Page_Init);
this.PreRender += new System.EventHandler(this.My_PreRender);
}

對(duì)于幾個(gè)沒(méi)有對(duì)應(yīng)事件的過(guò)程,比如2.Load ViewState,我們可以重載Page的虛函數(shù)protected override void LoadViewState(object savedState);來(lái)添加自己的控制代碼,不過(guò)切忌掉用基類的對(duì)應(yīng)方法,比如:
protected override void LoadViewState(object savedState)
{
//自己處理VIEWSTATE
base.LoadViewState (savedState);
}

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    一本色道久久综合狠狠躁| 久久精品a毛片看国产成人| 欧美日韩乱码一区二区三区| 欧美亚洲另类久久久精品| 日韩中文字幕视频在线高清版| 色无极东京热男人的天堂| 国产91麻豆精品成人区| 日韩女优精品一区二区三区| 日韩人妻欧美一区二区久久| 色婷婷在线精品国自产拍| 欧美不卡高清一区二区三区| 亚洲欧洲一区二区中文字幕| 亚洲一区二区三区四区性色av| 永久福利盒子日韩日韩| 国产真人无遮挡免费视频一区| 青青操成人免费在线视频| 欧美国产日韩变态另类在线看| 在线视频三区日本精品| 国产日产欧美精品大秀| 久草视频在线视频在线观看| 熟女免费视频一区二区| 欧美色欧美亚洲日在线| 国产精品香蕉免费手机视频| 夫妻性生活一级黄色录像| 麻豆精品在线一区二区三区| 一二区不卡不卡在线观看| 国产精品久久男人的天堂| 富婆又大又白又丰满又紧又硬| 日韩精品中文在线观看| 深夜福利欲求不满的人妻| 日韩人妻有码一区二区| 国产精品一区二区三区日韩av| 91久久精品国产成人| 亚洲性生活一区二区三区| 国产精品日韩欧美一区二区| 国产欧美一区二区久久| 婷婷伊人综合中文字幕| 国产精品久久男人的天堂| 91欧美视频在线观看免费| 精品人妻一区二区三区四区久久 | 欧美成人免费夜夜黄啪啪|