ASP.NET页面的声明周期
asp.net页面运行的时候将经历一个声明周期,这个生命周期中会进行一系列的操作,调用一系列的方法。了解asp.net页面的生命周期对于精确控制页面的控件呈现方式和行为非常重要。 一般说来一个常规页面要经历如下几个生命周期阶段:
阶段 | 说明 |
页请求 | 页请求发生在页生命周期开始之前。用户请求页时,ASP.NET 将确定是否需要分析和编译页(从而开始页的生命周期),或者是否可以在不运行页的情况下发送页的缓存版本以进 行响应 |
开始 | 在开始阶段,将设置页属性,如 Request 和 Response。在此阶段,页还将确定请求是回发请求还是新请求,并设置 IsPostBack 属性。此外,在开始阶段期间,还将设置页的 UICulture 属性 |
页初始化 | 页初始化期间,可以使用页中的控件,并将设置每个控件的 UniqueID 属性。此外,任何主题都将应用于页。如果当前请求是回发请求,则回发数据尚未加载,并且控件属性值尚 未还原为视图状态中的值 |
加载 | 加载期间,如果当前请求是回发请求,则将使用从视图状态和控件状态恢复的信息加载控件属性 |
验证 | 在验证期间,将调用所有验证程序控件的 Validate 方法,此方法将设置各个验证程序控件和页的 IsValid 属性 |
回发事件处理 | 如果请求是回发请求,则将调用所有事件处理程序 |
呈现 | 在呈现期间,视图状态将被保存到页,然后页将调用每个控件,以将其呈现的输出提供给页的 Response 属性的 OutputStream |
卸载 | 完全呈现页、将页发送至客户端并准备丢弃时,将调用卸载。此时,将卸载页属性(如 Response 和 Request)并执行清理 |
在页的生命周期中,一般会有如下事件:
页事件 | 典型使用 |
Page_PreInit | 使用 IsPostBack 属性确定是否是第一次处理该页。 创建或重新创建动态控件。 动态设置主控页。 动态设置 Theme 属性。 读取或设置配置文件属性值。 注意:如果请求是回发请求,则控件的值尚未从视图状态还原。如果在此阶段设置控件属性,则其值可能会在下一阶段被改写。 |
Page_Init | 读取或初始化控件属性 |
Page_Load | 读取和更新控件属性 |
Control events | 执行特定于应用程序的处理: 如果页包含验证程序控件,请在执行任何处理之前检查页和各个验证控件的 IsValid 属性。 处理特定事件,如 Button 控件的 Click 事件。 |
Page_PreRender | 对页的内容进行最后更改 |
Page_Unload | 执行最后的清理工作,可能包括: 关闭打开的文件和数据库连接。 完成日志记录或其他特定于请求的任务。 |
另外,Web应用程序是无状态的。每次请求一个新网页或者刷新页面服务器都会创建一个当前页的新实例,这就意味着无法获取页面的以前的信息,如果确实需要这么做,需要采用额外的机制。如我们新建一个index的单页页面,在其加上如下代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/
xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
string date;
protected void Page_Load(object sender, EventArgs e)
{
if (date == null)//如果date为空则设置为当前时间的字符串形式
{
date = DateTime.Now.ToString();
}
Response.Write("当前时间:"+date);
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>无标题页</title>
</head>
<body>
<form id="form1" runat="server">
<div>
</div>
</form>
</body>
</html>
按照正常理解,第一次运行的时候date字符串为null,会被设置成系统当前的字符串表示形式,并且输出,再次刷新的时候date字符串不再为空,会依然输出刚才的时间字符串,但是结果却不是这样。第一次运行的结果:
刷新页面之后的结果:
这就证明了即使是刷新当前页也会重新生成一个当前页面的实例,因为只有在生成页面新实例的情况下date字符串变量才为空,才会被重新设置值。
IsPostBack属性
Page类有一个IsPostBack属性,这个属性用来指示当前页面是第一次加载还是响应了页面上某个控件的服务器事件导致回发而加载。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
string data;
protected void Page_Load(object sender, EventArgs e)
{
if (data == null)
{
data = DateTime.Now.ToString();
}
Response.Write("当前的时间是:"+data);
if (!Page.IsPostBack)
{
Response.Write("这是第一次加载");
}
else
{
Response.Write("响应客户端回发而加载");
}
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="btnSubmit" runat="server" onclick="btnSubmit_Click" Text="提交" />
</div>
</form>
</body>
</html>
页面第一次运行的结果:
按刷新页面的结果:
点击一下“提交”按钮之后的结果:
按刷新页面的结果:
看到每次打开一个页面和刷新一个页面效果都是一样的,只有响应客户端回发时IsPostBack属性才是true。了解这个属性和服务器采用了一种机制来“记录”服务器控件的状态这种做法(其实利用了ViewState和ControlState机制)对于将来数据绑定会有很大作用。刷新需然重新生成了一个页面实例,但回发请求是将使用从视图状态和控件状态恢复的信息加载控件属性。刷新并不是第一次加载,而在地址栏按回车才会变为第一次加载。