ASP.NET 2.0中几个对象的主要方法/事件流程

根据Lutz Roeder的Reflector对System.Web.dll的反编译,下面是HttpApplication,Page和Control对象的主要方法和事件的流程

     PostBack
     Page/Control Event
     CallBack
HttpApplication Page Control
BeginRequest    
AuthenticateRequest    
DefaultAuthentication    
PostAuthenticateRequest    
AuthorizeRequest    
PostAuthorizeRequest    
ResolveRequestCache    
PostResolveRequestCache    
MapHttpHandler Construct  
PostMapRequestHandler    
AcquireRequestState (Session)    
PostAcquireRequestState    
PreRequestHandlerExecute    
CallHandler

DeterminePostBackMode

 
LoadScrollPosition  
PerformPreInit
PreInit
–InitializeThemes
–ApplyMasterPage
 
InitRecursive
(–ResolveAdapter
–ApplySkin
Init
–TrackViewState)
ResolveAdapter
InitRecursive
ApplySkin
Init
TrackViewState
InitComplete

 
LoadAllState
–LoadPageStateFromPersistenceMedium
–LoadViewStateRecursive

LoadControlStateInternal
–LoadControlState

LoadViewStateRecursive
–LoadViewState
ProcessPostData  
PreLoad  
LoadRecursive
(–Load)
LoadRecursive
Load
ProcessPostData  
RaiseChangedEvents  
RaisePostBackEvent  
LoadComplete  
RaiseCallbackEvent
–return

 
PreRenderRecursiveInternal
(–PreRender)

PreRenderRecursiveInternal
PreRender
ExecuteRegisteredAsyncTasks **  
PerformPreRenderComplete
PreRenderComplete
 
SaveAllState
–SaveViewStateRecursive
–SavePageStateToPersistenceMedium
SaveControlStateInternal
–SaveControlState
SaveViewState
–SaveViewStateRecursive
SaveStateComplete  
RenderControl

RenderControl
–RenderControlInternal
—-Render
——RenderChildren
——–RenderChildrenInternal
PostRequestHandlerExecute    
ReleaseRequestState (Session)    
PostReleaseRequestState    
CallFilter — Response.FilterOutput    
UpdateRequestCache    
PostUpdateRequestCache    
EndRequest    

** 参考 Jeff Prosise在MSND杂志10月期的文章
Asynchronous Pages in ASP.NET 2.0

ASP.NET 2.0中几个对象的主要方法/事件流程

根据Lutz Roeder的Reflector对System.Web.dll的反编译,下面是HttpApplication,Page和Control对象的主要方法和事件的流程

     PostBack
     Page/Control Event
     CallBack
HttpApplication Page Control
BeginRequest    
AuthenticateRequest    
DefaultAuthentication    
PostAuthenticateRequest    
AuthorizeRequest    
PostAuthorizeRequest    
ResolveRequestCache    
PostResolveRequestCache    
MapHttpHandler Construct  
PostMapRequestHandler    
AcquireRequestState (Session)    
PostAcquireRequestState    
PreRequestHandlerExecute    
CallHandler

DeterminePostBackMode

 
LoadScrollPosition  
PerformPreInit
PreInit
–InitializeThemes
–ApplyMasterPage
 
InitRecursive
(–ResolveAdapter
–ApplySkin
Init
–TrackViewState)
ResolveAdapter
InitRecursive
ApplySkin
Init
TrackViewState
InitComplete

 
LoadAllState
–LoadPageStateFromPersistenceMedium
–LoadViewStateRecursive

LoadControlStateInternal
–LoadControlState

LoadViewStateRecursive
–LoadViewState
ProcessPostData  
PreLoad  
LoadRecursive
(–Load)
LoadRecursive
Load
ProcessPostData  
RaiseChangedEvents  
RaisePostBackEvent  
LoadComplete  
RaiseCallbackEvent
–return

 
PreRenderRecursiveInternal
(–PreRender)

PreRenderRecursiveInternal
PreRender
ExecuteRegisteredAsyncTasks **  
PerformPreRenderComplete
PreRenderComplete
 
SaveAllState
–SaveViewStateRecursive
–SavePageStateToPersistenceMedium
SaveControlStateInternal
–SaveControlState
SaveViewState
–SaveViewStateRecursive
SaveStateComplete  
RenderControl

RenderControl
–RenderControlInternal
—-Render
——RenderChildren
——–RenderChildrenInternal
PostRequestHandlerExecute    
ReleaseRequestState (Session)    
PostReleaseRequestState    
CallFilter — Response.FilterOutput    
UpdateRequestCache    
PostUpdateRequestCache    
EndRequest    

** 参考 Jeff Prosise在MSND杂志10月期的文章
Asynchronous Pages in ASP.NET 2.0

Scott Guthrie最近的blog文章

ASP.NET之父Scott Guthrie,最近在他的blog上登出了一连串有关ASP.NET 2.0和VS 2005的文章,

1。VS 2005中的Web项目系统提供的新功能 (VS 2005 Web Project System: What is it and why did we do it?)

2。如何在VS 2005和Web项目系统中使用 IIS (Using IIS with VS 2005 and the new Web Project system)

3。如何设置 ASP.NET 2.0的应用服务使用SQL Server 2000和SQL Server 2005 (Configuring ASP.NET 2.0 Application Services to use SQL Server 2000 or SQL Server 2005)

4。更好地管理VS 2005Web项目中文件的几个技巧 (Some techniques for better managing files in VS 2005 Web Projects)

5。如何使用VS 2005建立可重用的ASP.NET用户控件和页面库 (Building Re-Usable ASP.NET User Control and Page Libraries with VS 2005)

在Page类的构造函数里, 为什么HttpContext.Current.Session是null?

(兼回答CSDN论坛的一个问题)

因为Session是在HttpApplication的AcquireRequestState事件后才有的,而Page类(或其他HttpHandler)的对象是在此之前生成的,看一下HttpApplication的事件次序

BeginRequest
AuthenticateRequest
AuthorizeRequest
ResolveRequestCache
—-Page类(或其他HttpHandler)的对象在此生成
AcquireRequestState
PreRequestHandlerExecute
—-Page类(或其他HttpHandler)的对象的ProcessRequest
PostRequestHandlerExecute
ReleaseRequestState
UpdateRequestCache
EndRequest

如果你想深入了解ASP.NET处理请求过程,参考Rick Strahl的文章

A low-level Look at the ASP.NET Architecture

给静态DataGrid动态添加列的问题

这个问题反复在论坛出现,其实这个问题在MSDN上早就有答案
1。英文版:Top Questions about the DataGrid Web Server Control(Mike Pope and Nikhil Kothari)
2。中文版:DataGrid Web 伺服器控制项的常见问题

可惜,论坛上的风气不太好,你即使给了连接,真正去看的人大概并不多

诀窍是,如果动态添加了列的话,需要在下一次PostBack时,在LoadViewState或更早把这些列重新添加。原因是,在Page类递归调用LoadViewState时,会调用DataGrid的CreateChildControls,而DataGrid的(实际上是它的父类的实现)CreateChildControls会调用DataGrid的CreateControlHierarchy()方法。在其中,DataGrid会根据当前的列的数目构造DataGridItem里的东西,然后从ViewState里恢复原来的数据。如果你没有重新添加你的动态列的话,你的动态列在PostBack后就会消失,更不用谈触发列里的控件的事件了

检验你的动态控件在PostBack后是否还在的一个方法是,加一个按钮看PostBack后的行为

下面是一个简单的测试

<html>
<body>
<form runat=”server”>
<asp:DataGrid id=”DataGrid1″ runat=”server”
GridLines=”Both” AutoGenerateColumns=”false”
OnItemCommand=”DataGrid1_ItemCommand”>
 <Columns>
 <asp:ButtonColumn HeaderText=”Static Button” Text=”Click Me”
 CommandName=”Static”/>
 <asp:TemplateColumn HeaderText=”Data”>
  <ItemTemplate><%#Container.DataItem%></ItemTemplate>
 </asp:TemplateColumn>
 </Columns>
</asp:DataGrid>
<asp:Button id=”btnAddAColumn” runat=”server” Text=”Add a column” OnClick=”AddButtonColumn”/>
<asp:Button id=”btnRefresh” runat=”server” Text=”Refresh” />
</form>
</body>
</html>

void BindGrid()
{
 DataGrid1.DataSource = new string[] {“a”,”b”,”c”};
 DataGrid1.DataBind();
}

void Page_Load(object sender, EventArgs e)
{
  if (!IsPostBack)
  {
 BindGrid();
  }
}

void DataGrid1_ItemCommand(Object sender, DataGridCommandEventArgs e)
{
 Response.Write(“ItemCommand is called
“);
 LinkButton btn = e.CommandSource as LinkButton;
 if (btn != null)
  Response.Write(String.Format(“{0} is clicked on row {1}”, btn.CommandName, e.Item.ItemIndex));
        
}

//lifted from the original post
public void CreateGridColumn(DataGrid OperationDataGrid)
{
   ButtonColumn NewButCol = new ButtonColumn() ;
   NewButCol.Text = “编辑” ;
   NewButCol.HeaderText = “操作” ;
   NewButCol.CommandName = “Edit” ;
   NewButCol.ButtonType = ButtonColumnType.LinkButton;
   NewButCol.Visible = true ;
   OperationDataGrid.Columns.Add(NewButCol) ;
   //OperationDataGrid.Columns.AddAt(1,NewButCol) ;
}

bool ButtonAdded
{
 get {
  object o = ViewState[“ButtonAdded”];
  if (o == null)
   return false;
  else return (bool)o;
     }
 set { ViewState[“ButtonAdded”] = value;}
}

void AddButtonColumn(object sender, EventArgs e)
{
 CreateGridColumn(DataGrid1);
 ButtonAdded = true;
 BindGrid();
 btnAddAColumn.Visible = false;
}

protected override void LoadViewState(object savedState)
{
 base.LoadViewState(savedState);
 
//在这里重新添加,假如已经添加的话
 if (ButtonAdded)
 CreateGridColumn(DataGrid1);
}