两个粒度看Asp.net生命周期

本文详细介绍了ASP.NET页面生命周期中的关键阶段,包括页面事件触发顺序和Page类内部处理请求的具体流程。通过示例代码展示了从预初始化到卸载的整个过程,并提供了Reflector观察Page类内部实现的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于Asp.net页面层开发无论是写页面还是写控件,我觉得都可以用一句话描述:"Do the right thing at the right time in the right place."这是07年底的一篇东西,还是有点价值整理出来与大家共享。

本文从两个粒度对Asp.net生命周期做了展示,一是通过记录页面事件的触发顺序看请求的处理流程,一是通过ReflectorPage类内部对请求处理的实现,为了清晰我清理掉了ETW相关的代码保留了一个简化却足可以说明问题的流程骨架;

本文覆盖以下内容:

  1. 页面事件的触发顺序展示
  2. 清理掉ETW代码后的,Page类内部对请求处理的实现
  3. MSDN关于Asp.net生命周期非常重要的四个表格
  4. 演示源代码下载


1None.gifusingSystem;
2None.gifusingSystem.Configuration;
3None.gifusingSystem.Data;
4None.gifusingSystem.Web;
5None.gifusingSystem.Web.Security;
6None.gifusingSystem.Web.UI;
7None.gifusingSystem.Web.UI.HtmlControls;
8None.gifusingSystem.Web.UI.WebControls;
9None.gifusingSystem.Web.UI.WebControls.WebParts;
10None.gif
11None.gifpublicpartialclass_Default:System.Web.UI.Page
12ExpandedBlockStart.gifContractedBlock.gifdot.gif{
13InBlock.gifprotectedvoidPage_PreInit(objectsender,EventArgse)
14ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
15InBlock.gifResponse.Write("Page_PreInit<br/>");
16ExpandedSubBlockEnd.gif}

17InBlock.gifprotectedvoidPage_Init(objectsender,EventArgse)
18ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
19InBlock.gifResponse.Write("Page_Init<br/>");
20InBlock.gif
21ExpandedSubBlockEnd.gif}

22InBlock.gifprotectedvoidPage_InitComplete(objectsender,EventArgse)
23ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
24InBlock.gifResponse.Write("Page_InitComplete<br/>");
25InBlock.gif
26ExpandedSubBlockEnd.gif}

27InBlock.gifprotectedvoidPage_PreLoad(objectsender,EventArgse)
28ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
29InBlock.gifResponse.Write("Page_PreLoad<br/>");
30InBlock.gif
31ExpandedSubBlockEnd.gif}

32InBlock.gifprotectedvoidPage_Load(objectsender,EventArgse)
33ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
34InBlock.gifResponse.Write("Page_Load<br/>");
35InBlock.gif
36ExpandedSubBlockEnd.gif}

37InBlock.gifprotectedvoidPage_LoadComplete(objectsender,EventArgse)
38ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
39InBlock.gifResponse.Write("Page_LoadComplete<br/>");
40InBlock.gif
41ExpandedSubBlockEnd.gif}

42InBlock.gifprotectedvoidPage_PreRender(objectsender,EventArgse)
43ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
44InBlock.gifResponse.Write("Page_PreRender<br/>");
45InBlock.gif
46ExpandedSubBlockEnd.gif}

47InBlock.gifprotectedvoidPage_SaveStateComplete(objectsender,EventArgse)
48ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
49InBlock.gifResponse.Write("Page_SaveStateComplete<br/>");
50InBlock.gif
51ExpandedSubBlockEnd.gif}

52InBlock.gif
53InBlock.gif
54InBlock.gifprotectedvoidPage_Unload(objectsender,EventArgse)
55ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
56InBlock.gifinti=0;
57InBlock.gifi++;//这行代码是用来设置断点的,为什么不用Response.Write?你说呢?
58InBlock.gif
59ExpandedSubBlockEnd.gif}

60InBlock.gif
61InBlock.gif
62InBlock.gifprotectedvoidButton1_Click(objectsender,EventArgse)
63ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
64InBlock.gifLabel1.Text="ControlEvent";
65InBlock.gifResponse.Write("Button事件触发!<br/>");
66ExpandedSubBlockEnd.gif}

67ExpandedBlockEnd.gif}

68None.gif
69None.gif
70None.gif

运行结果:

Page_PreInit

Page_Init

Page_InitComplete

Page_PreLoad

Page_Load

Page_LoadComplete

Page_PreRender

Page_SaveStateComplete


点击页面的Button后的输出:

Page_PreInit

Page_Init

Page_InitComplete

Page_PreLoad

Page_Load

Button事件触发!

Page_LoadComplete

Page_PreRender

Page_SaveStateComplete

我们从一个更细的粒度,在Reflector中看Page对请求处理的代码:

1privatevoidProcessRequestMain(boolincludeStagesBeforeAsyncPoint,boolincludeStagesAfterAsyncPoint)
2{
3try
4{
5HttpContextcontext=this.Context;
6stringstr=null;
7if(includeStagesBeforeAsyncPoint)
8{
9if(this.IsInAspCompatMode)
10{
11AspCompatApplicationStep.OnPageStartSessionObjects();
12}
13if(this.PageAdapter!=null)
14{
15this._requestValueCollection=this.PageAdapter.DeterminePostBackMode();
16}
17else
18{
19this._requestValueCollection=this.DeterminePostBackMode();
20}
21stringcallbackControlID=string.Empty;
22if(this.DetermineIsExportingWebPart())
23{
24if(!RuntimeConfig.GetAppConfig().WebParts.EnableExport)
25{
26thrownewInvalidOperationException(SR.GetString("WebPartExportHandler_DisabledExportHandler"));
27}
28str=this.Request.QueryString["webPart"];
29if(string.IsNullOrEmpty(str))
30{
31thrownewInvalidOperationException(SR.GetString("WebPartExportHandler_InvalidArgument"));
32}
33if(string.Equals(this.Request.QueryString["scope"],"shared",StringComparison.OrdinalIgnoreCase))
34{
35this._pageFlags.Set(4);
36}
37stringstr3=this.Request.QueryString["query"];
38if(str3==null)
39{
40str3=string.Empty;
41}
42this.Request.QueryStringText=str3;
43context.Trace.IsEnabled=false;
44}
45if(this._requestValueCollection!=null)
46{
47if(this._requestValueCollection["__VIEWSTATEENCRYPTED"]!=null)
48{
49this.ContainsEncryptedViewState=true;
50}
51callbackControlID=this._requestValueCollection["__CALLBACKID"];
52if((callbackControlID!=null)&&(this._request.HttpVerb==HttpVerb.POST))
53{
54this._isCallback=true;
55}
56elseif(!this.IsCrossPagePostBack)
57{
58VirtualPathpath=null;
59if(this._requestValueCollection["__PREVIOUSPAGE"]!=null)
60{
61try
62{
63path=VirtualPath.CreateNonRelativeAllowNull(DecryptString(this._requestValueCollection["__PREVIOUSPAGE"]));
64}
65catch(CryptographicException)
66{
67this._pageFlags[8]=true;
68}
69if((path!=null)&&(path!=this.Request.CurrentExecutionFilePathObject))
70{
71this._pageFlags[8]=true;
72this._previousPagePath=path;
73}
74}
75}
76}
77if(this.MaintainScrollPositionOnPostBack)
78{
79this.LoadScrollPosition();
80}
81
82this.PerformPreInit();
83
84this.InitRecursive(null);
85
86this.OnInitComplete(EventArgs.Empty);
87
88if(this.IsPostBack)
89{
90this.LoadAllState();
91
92this.ProcessPostData(this._requestValueCollection,true);
93
94}
95
96
97this.OnPreLoad(EventArgs.Empty);
98
99this.LoadRecursive();
100
101if(this.IsPostBack)
102{
103this.ProcessPostData(this._leftoverPostData,false);
104
105this.RaiseChangedEvents();
106
107this.RaisePostBackEvent(this._requestValueCollection);
108
109}
110
111this.OnLoadComplete(EventArgs.Empty);
112
113if(this.IsPostBack&&this.IsCallback)
114{
115this.PrepareCallback(callbackControlID);
116}
117elseif(!this.IsCrossPagePostBack)
118{
119
120this.PreRenderRecursiveInternal();
121}
122}
123if((this._asyncInfo==null)||this._asyncInfo.CallerIsBlocking)
124{
125this.ExecuteRegisteredAsyncTasks();
126}
127if(includeStagesAfterAsyncPoint)
128{
129if(this.IsCallback)
130{
131this.RenderCallback();
132}
133elseif(!this.IsCrossPagePostBack)
134{
135this.PerformPreRenderComplete();
136
137if(context.TraceIsEnabled)
138{
139this.BuildPageProfileTree(this.EnableViewState);
140this.Trace.Write("aspx.page","BeginSaveState");
141}
142
143this.SaveAllState();
144
145this.OnSaveStateComplete(EventArgs.Empty);
146if(str!=null)
147{
148this.ExportWebPart(str);
149}
150else
151{
152this.RenderControl(this.CreateHtmlTextWriter(this.Response.Output));
153}
154
155this.CheckRemainingAsyncTasks(false);
156}
157}
158}
159catch(ThreadAbortExceptionexception)
160{
161HttpApplication.CancelModuleExceptionexceptionState=exception.ExceptionStateasHttpApplication.CancelModuleException;
162if(((!includeStagesBeforeAsyncPoint||!includeStagesAfterAsyncPoint)||((this._context.Handler!=this)||(this._context.ApplicationInstance==null)))||((exceptionState==null)||exceptionState.Timeout))
163{
164this.CheckRemainingAsyncTasks(true);
165throw;
166}
167this._context.ApplicationInstance.CompleteRequest();
168Thread.ResetAbort();
169}
170catch(ConfigurationException)
171{
172throw;
173}
174catch(Exceptionexception3)
175{
176PerfCounters.IncrementCounter(AppPerfCounter.ERRORS_DURING_REQUEST);
177PerfCounters.IncrementCounter(AppPerfCounter.ERRORS_TOTAL);
178if(!this.HandleError(exception3))
179{
180throw;
181}
182}
183}
184
185
186
187
188
privatevoidPerformPreInit()
{
this.OnPreInit(EventArgs.Empty);
this.InitializeThemes();//看到主题和模板页是什么时候加载了吧
this.ApplyMasterPage();
this._preInitWorkComplete=true;
}


MSDN上对Asp.net生命周期解释有非常重要的四个表格:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值