服务器端的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); } } } }