服務器端的page類
所有我們編寫的頁面都繼承自page類,可見page類是非常重要的,page類提供了哪些功能,直接決定了我們的頁面類可以繼承什么功能,或者說,直接決定了我們的頁面類功能的強大與否!那么,page類實現了什么功能呢?如前所述的三個客戶端的事實,頁面類要管理ViewState,還要管理事件。page類起碼要提供這些功能以供我們的頁面類重載或者調用。
page類提供了四個順序執行的事件Init,Load,PreRender和Unload,這四個事件是一條主線,依次標明了page類執行的各個階段。
- init事件發生在所有服務器端控件的狀態(ViewState)被存儲之前。
- load事件發生在所有服務器端控件的狀態被存儲之后和所有的事件被觸發之前。
- PreRender事件發生在所有事件被觸發之后和要回發給客戶端的html還沒有回發(這個過程也叫"呈現")之前。
- unload事件發生在所有html都回發完成以后。從這四個事件可以看到page類的大致執行步驟。
詳細的page類事件順序是這樣的:
- ->獲得客戶端的post請求
- ->page類的繼承類被構造
- ->page類的ProcessRequest方法被調用
- ->init事件被執行
- ->page類的虛函數CreateChildControls被調用
- ->服務器端控件的狀態(來自post變量和ViewState)被存儲
- ->load事件被執行
- ->我們自定義的服務器端控件的事件被執行
- ->PreRender事件被執行
- ->page類的虛函數Render方法被調用
- ->page類的虛函數RenderChildren方法被調用
- ->Http響應發往客戶端->unload事件被執行
- ->page類的繼承類被解構。
我們知道一個頁面上的控件很多是包含(父子)關系,所以這里的CreateChildControls和RenderChinldren函數應該就不難理解了。
這個事件順序是理解asp.net頁面類的關鍵,和前面客戶端的三個事實結合起來理解,就可以解釋asp.net怎么樣把客戶端和服務器端結合起來,從而實現從腳本編程轉移到面向對象編程。無論是微軟提供的webcontrols,或者是用戶自定義控件,涉及到客戶端和服務器端交互,原理都與此類似。
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace CommonClass
{
/// <summary>
/// 頁面的基類。 ///
/// </summary>
public class PageBase:System.Web.UI.Page
{
public PageBase()
{
//
// TODO: 在此處添加構造函數邏輯
//
}
/// <summary>
/// 模塊名稱
/// </summary>
public String ModuleName
{
set{ViewState["ModuleName"]=value;}
get{return ViewState["ModuleName"].ToString();}
}
private string _Message;
/// <summary>
/// 向用戶顯示信息提示
/// </summary>
public String Message
{
get{return _Message;}
set{_Message = value;}
}
/// <summary>
/// 檢查是否有特定的權限
/// </summary>
/// <param name="sec">安全選項</param>
/// <returns></returns>
// public bool CheckPermissionSuccess(Framework.SecurityOption sec)
// {
// //TODO:實現Framework.Security類,如瀏覽、修改、管理權限
// return Framework.Security.CheckValid(this.ModuleName,sec);
// }
/// <summary>
/// 頁最頂端的PlaceHolder
/// </summary>
public System.Web.UI.WebControls.PlaceHolder plhTopHolder;
/// <summary>
/// 頁最底端的PlaceHolder
/// </summary>
public System.Web.UI.WebControls.PlaceHolder plhBottomHolder;
protected override void OnInit(EventArgs e)
{
//初始化控件
plhTopHolder = new PlaceHolder();
plhBottomHolder = new PlaceHolder();
//添加頂端PlaceHolder
Control form1 = this.FindControl("Form1");
if (form1 != null) form1.Controls.AddAt(0,plhTopHolder);
//添加頁眉的用戶自定義控件
ITemplate Header = Page.LoadTemplate("~/Controls/Header.ascx");
this.plhTopHolder.Controls.Add(Header);
//event
this.Load+=new EventHandler(PageBase_Load);
this.Error+=new EventHandler(PageBase_Error);
this.PreRender+=new EventHandler(PageBase_PreRender);
base.OnInit (e);
}
private void PageBase_Load(object sender, EventArgs e)
{
//添加底端PlaceHolder
Control form1 = this.FindControl("Form1");
if (form1 != null) form1.Controls.Add(plhBottomHolder);
//添加頁腳的用戶自定義控件
//ITemplate Footer = Page.LoadTemplate("~/Controls/Footer.ascx");
//this.plhBottomHolder.Controls.Add(Footer);
}
private void PageBase_Error(object sender, EventArgs e)
{
#if !Debug
// Exception exc = Server.GetLastError();
// 記錄未處理的錯誤
// XMLLog.AddErrorLog(exc,userName);
// Server.Transfer("~/PageError.aspx?error=" + Server.HtmlEncode(exc.Message));
#endif
}
private void PageBase_PreRender(object sender, EventArgs e)
{
//添加信息提示
if (this._Message != null && this._Message != String.Empty)
{
LiteralControl litMessage = new LiteralControl("<div class=\"CssMessage\"><p>" + Message + "</p></div>");
plhTopHolder.Controls.Add(litMessage);
}
}
}
}
