asp.net Page事件处理管道
我们知道页面就是一个处理程序,里面的实现非常复杂,网上也有很多资料讲到asp.net的管道处理,有关page的事件处理也不少;这里我就page的事件处理结果如图:
这里的总结来至asp.net本质论。我们也知道page的处理都集中在一个ProcessRequest方法中,该方法最终主要还是调用ProcessRequestMain方法。其主要实现如下:
private void ProcessRequestMain( bool includeStagesBeforeAsyncPoint, bool includeStagesAfterAsyncPoint) { try { HttpContext context = this .Context; string str = null ; if (includeStagesBeforeAsyncPoint) { if ( this .IsInAspCompatMode) { AspCompatApplicationStep.OnPageStartSessionObjects(); } if ( this .PageAdapter != null ) { this ._requestValueCollection = this .PageAdapter.DeterminePostBackMode(); if ( this ._requestValueCollection != null ) { this ._unvalidatedRequestValueCollection = this .PageAdapter.DeterminePostBackModeUnvalidated(); } } else { this ._requestValueCollection = this .DeterminePostBackMode(); if ( this ._requestValueCollection != null ) { this ._unvalidatedRequestValueCollection = this .DeterminePostBackModeUnvalidated(); } } string callbackControlID = string .Empty; if ( this .DetermineIsExportingWebPart()) { if (!RuntimeConfig.GetAppConfig().WebParts.EnableExport) { throw new InvalidOperationException(SR.GetString( "WebPartExportHandler_DisabledExportHandler" )); } str = this .Request.QueryString[ "webPart" ]; if ( string .IsNullOrEmpty(str)) { throw new InvalidOperationException(SR.GetString( "WebPartExportHandler_InvalidArgument" )); } if ( string .Equals( this .Request.QueryString[ "scope" ], "shared" , StringComparison.OrdinalIgnoreCase)) { this ._pageFlags.Set(4); } string str3 = this .Request.QueryString[ "query" ]; if (str3 == null ) { str3 = string .Empty; } this .Request.QueryStringText = str3; context.Trace.IsEnabled = false ; } if ( this ._requestValueCollection != null ) { if ( this ._requestValueCollection[ "__VIEWSTATEENCRYPTED" ] != null ) { this .ContainsEncryptedViewState = true ; } callbackControlID = this ._requestValueCollection[ "__CALLBACKID" ]; if ((callbackControlID != null ) && ( this ._request.HttpVerb == HttpVerb.POST)) { this ._isCallback = true ; } else if (! this .IsCrossPagePostBack) { VirtualPath path = null ; if ( this ._requestValueCollection[ "__PREVIOUSPAGE" ] != null ) { try { path = VirtualPath.CreateNonRelativeAllowNull(DecryptString( this ._requestValueCollection[ "__PREVIOUSPAGE" ], Purpose.WebForms_Page_PreviousPageID)); } catch { this ._pageFlags[8] = true ; } if ((path != null ) && (path != this .Request.CurrentExecutionFilePathObject)) { this ._pageFlags[8] = true ; this ._previousPagePath = path; } } } } if ( this .MaintainScrollPositionOnPostBack) { this .LoadScrollPosition(); } if (context.TraceIsEnabled) { this .Trace.Write( "aspx.page" , "Begin PreInit" ); } this .PerformPreInit(); if (context.TraceIsEnabled) { this .Trace.Write( "aspx.page" , "End PreInit" ); } if (context.TraceIsEnabled) { this .Trace.Write( "aspx.page" , "Begin Init" ); } this .InitRecursive( null ); if (context.TraceIsEnabled) { this .Trace.Write( "aspx.page" , "End Init" ); } if (context.TraceIsEnabled) { this .Trace.Write( "aspx.page" , "Begin InitComplete" ); } this .OnInitComplete(EventArgs.Empty); if (context.TraceIsEnabled) { this .Trace.Write( "aspx.page" , "End InitComplete" ); } if ( this .IsPostBack) { if (context.TraceIsEnabled) { this .Trace.Write( "aspx.page" , "Begin LoadState" ); } this .LoadAllState(); if (context.TraceIsEnabled) { this .Trace.Write( "aspx.page" , "End LoadState" ); this .Trace.Write( "aspx.page" , "Begin ProcessPostData" ); } this .ProcessPostData( this ._requestValueCollection, true ); if (context.TraceIsEnabled) { this .Trace.Write( "aspx.page" , "End ProcessPostData" ); } } if (context.TraceIsEnabled) { this .Trace.Write( "aspx.page" , "Begin PreLoad" ); } this .OnPreLoad(EventArgs.Empty); if (context.TraceIsEnabled) { this .Trace.Write( "aspx.page" , "End PreLoad" ); } if (context.TraceIsEnabled) { this .Trace.Write( "aspx.page" , "Begin Load" ); } this .LoadRecursive(); if (context.TraceIsEnabled) { this .Trace.Write( "aspx.page" , "End Load" ); } if ( this .IsPostBack) { if (context.TraceIsEnabled) { this .Trace.Write( "aspx.page" , "Begin ProcessPostData Second Try" ); } this .ProcessPostData( this ._leftoverPostData, false ); if (context.TraceIsEnabled) { this .Trace.Write( "aspx.page" , "End ProcessPostData Second Try" ); this .Trace.Write( "aspx.page" , "Begin Raise ChangedEvents" ); } this .RaiseChangedEvents(); if (context.TraceIsEnabled) { this .Trace.Write( "aspx.page" , "End Raise ChangedEvents" ); this .Trace.Write( "aspx.page" , "Begin Raise PostBackEvent" ); } this .RaisePostBackEvent( this ._requestValueCollection); if (context.TraceIsEnabled) { this .Trace.Write( "aspx.page" , "End Raise PostBackEvent" ); } } if (context.TraceIsEnabled) { this .Trace.Write( "aspx.page" , "Begin LoadComplete" ); } this .OnLoadComplete(EventArgs.Empty); if (context.TraceIsEnabled) { this .Trace.Write( "aspx.page" , "End LoadComplete" ); } if ( this .IsPostBack && this .IsCallback) { this .PrepareCallback(callbackControlID); } else if (! this .IsCrossPagePostBack) { if (context.TraceIsEnabled) { this .Trace.Write( "aspx.page" , "Begin PreRender" ); } this .PreRenderRecursiveInternal(); if (context.TraceIsEnabled) { this .Trace.Write( "aspx.page" , "End PreRender" ); } } } if (( this ._legacyAsyncInfo == null ) || this ._legacyAsyncInfo.CallerIsBlocking) { this .ExecuteRegisteredAsyncTasks(); } this .ValidateRawUrlIfRequired(); if (includeStagesAfterAsyncPoint) { if ( this .IsCallback) { this .RenderCallback(); } else if (! this .IsCrossPagePostBack) { if (context.TraceIsEnabled) { this .Trace.Write( "aspx.page" , "Begin PreRenderComplete" ); } this .PerformPreRenderComplete(); if (context.TraceIsEnabled) { this .Trace.Write( "aspx.page" , "End PreRenderComplete" ); } if (context.TraceIsEnabled) { this .BuildPageProfileTree( this .EnableViewState); this .Trace.Write( "aspx.page" , "Begin SaveState" ); } this .SaveAllState(); if (context.TraceIsEnabled) { this .Trace.Write( "aspx.page" , "End SaveState" ); this .Trace.Write( "aspx.page" , "Begin SaveStateComplete" ); } this .OnSaveStateComplete(EventArgs.Empty); if (context.TraceIsEnabled) { this .Trace.Write( "aspx.page" , "End SaveStateComplete" ); this .Trace.Write( "aspx.page" , "Begin Render" ); } if (str != null ) { this .ExportWebPart(str); } else { this .RenderControl( this .CreateHtmlTextWriter( this .Response.Output)); } if (context.TraceIsEnabled) { this .Trace.Write( "aspx.page" , "End Render" ); } this .CheckRemainingAsyncTasks( false ); } } } catch (ConfigurationException) { throw ; } } |
在这个方法中有两段代码比较有意思
this.OnInitComplete(EventArgs.Empty);
if (context.TraceIsEnabled)
{
this.Trace.Write("aspx.page", "End InitComplete");
}
if (this.IsPostBack)
{
if (context.TraceIsEnabled)
{
this.Trace.Write("aspx.page", "Begin LoadState");
}
this.LoadAllState();
if (context.TraceIsEnabled)
{
this.Trace.Write("aspx.page", "End LoadState");
this.Trace.Write("aspx.page", "Begin ProcessPostData");
}
this.ProcessPostData(this._requestValueCollection, true);
if (context.TraceIsEnabled)
{
this.Trace.Write("aspx.page", "End ProcessPostData");
}
}
if (context.TraceIsEnabled)
{
this.Trace.Write("aspx.page", "Begin PreLoad");
}
this.OnPreLoad(EventArgs.Empty);
和
this.LoadRecursive();
if (context.TraceIsEnabled)
{
this.Trace.Write("aspx.page", "End Load");
}
if (this.IsPostBack)
{
if (context.TraceIsEnabled)
{
this.Trace.Write("aspx.page", "Begin ProcessPostData Second Try");
}
this.ProcessPostData(this._leftoverPostData, false);
if (context.TraceIsEnabled)
{
this.Trace.Write("aspx.page", "End ProcessPostData Second Try");
this.Trace.Write("aspx.page", "Begin Raise ChangedEvents");
}
this.RaiseChangedEvents();
if (context.TraceIsEnabled)
{
this.Trace.Write("aspx.page", "End Raise ChangedEvents");
this.Trace.Write("aspx.page", "Begin Raise PostBackEvent");
}
this.RaisePostBackEvent(this._requestValueCollection);
if (context.TraceIsEnabled)
{
this.Trace.Write("aspx.page", "End Raise PostBackEvent");
}
}
if (context.TraceIsEnabled)
{
this.Trace.Write("aspx.page", "Begin
LoadComplete");
}
this.OnLoadComplete(EventArgs.Empty);
整过post过来的请求与get相比就多了这中间一点处理,我们也知道page在处理post请求时需要处理数据的加载IPostBackDataHandler和事件的触发IPostBackEventHandler.
所以为什么这回分成两段就比较好理解了。
有关他们的介绍如下:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构