对于Asp.net页面层开发无论是写页面还是写控件,我觉得都可以用一句话描述:"Do the right thing at the right time in the right place."这是07年底的一篇东西,还是有点价值整理出来与大家共享。
本文从两个粒度对Asp.net生命周期做了展示,一是通过记录页面事件的触发顺序看请求的处理流程,一是通过Reflector看Page类内部对请求处理的实现,为了清晰我清理掉了ETW相关的代码保留了一个简化却足可以说明问题的流程骨架;
本文覆盖以下内容:
- 页面事件的触发顺序展示
- 清理掉ETW代码后的,Page类内部对请求处理的实现
- MSDN关于Asp.net生命周期非常重要的四个表格
- 演示源代码下载
1
usingSystem;
2
usingSystem.Configuration;
3
usingSystem.Data;
4
usingSystem.Web;
5
usingSystem.Web.Security;
6
usingSystem.Web.UI;
7
usingSystem.Web.UI.HtmlControls;
8
usingSystem.Web.UI.WebControls;
9
usingSystem.Web.UI.WebControls.WebParts;
10
11
publicpartialclass_Default:System.Web.UI.Page
12

{
13
protectedvoidPage_PreInit(objectsender,EventArgse)
14

{
15
Response.Write("Page_PreInit<br/>");
16
}
17
protectedvoidPage_Init(objectsender,EventArgse)
18

{
19
Response.Write("Page_Init<br/>");
20
21
}
22
protectedvoidPage_InitComplete(objectsender,EventArgse)
23

{
24
Response.Write("Page_InitComplete<br/>");
25
26
}
27
protectedvoidPage_PreLoad(objectsender,EventArgse)
28

{
29
Response.Write("Page_PreLoad<br/>");
30
31
}
32
protectedvoidPage_Load(objectsender,EventArgse)
33

{
34
Response.Write("Page_Load<br/>");
35
36
}
37
protectedvoidPage_LoadComplete(objectsender,EventArgse)
38

{
39
Response.Write("Page_LoadComplete<br/>");
40
41
}
42
protectedvoidPage_PreRender(objectsender,EventArgse)
43

{
44
Response.Write("Page_PreRender<br/>");
45
46
}
47
protectedvoidPage_SaveStateComplete(objectsender,EventArgse)
48

{
49
Response.Write("Page_SaveStateComplete<br/>");
50
51
}
52
53
54
protectedvoidPage_Unload(objectsender,EventArgse)
55

{
56
inti=0;
57
i++;//这行代码是用来设置断点的,为什么不用Response.Write?你说呢?
58
59
}
60
61
62
protectedvoidButton1_Click(objectsender,EventArgse)
63

{
64
Label1.Text="ControlEvent";
65
Response.Write("Button事件触发!<br/>");
66
}
67
}
68
69
70

2

3

4

5

6

7

8

9

10

11

12



13

14



15

16

17

18



19

20

21

22

23



24

25

26

27

28



29

30

31

32

33



34

35

36

37

38



39

40

41

42

43



44

45

46

47

48



49

50

51

52

53

54

55



56

57

58

59

60

61

62

63



64

65

66

67

68

69

70

运行结果:
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
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;
}
{
this.OnPreInit(EventArgs.Empty);
this.InitializeThemes();//看到主题和模板页是什么时候加载了吧
this.ApplyMasterPage();
this._preInitWorkComplete=true;
}
MSDN上对Asp.net生命周期解释有非常重要的四个表格: