Asp.Net 页面生命周期浅析
引言:
先提起初做项目时遇到的一个问题,即通过基本登陆页面(如下图示),点击登陆按钮,验证用户名、密码正确后,跳转至该用户的Main页面:
登陆页面的后台代码如下:
public partial class Login : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//为了获得在每次登录时都可以以HF开头
txt_UserID.Text = "HF";
txt_UserID.Focus();
}
protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
{
string userID = txt_UserID.Text.ToString().Trim();
UserBll userBll = new UserBll();
List<UserInfo> userList=userBll.GetUserByID_LoginToMain(userID);
string userName = userList[0].UserName;
string userPsw = userList[0].UserPsw;
string styleID = userList[0].StyleID.ToString().Trim();
string departID = userList[0].DepartID.ToString().Trim();
string email = userList[0].Email.ToString().Trim();
//判断工号以及密码输入
if (txt_UserID.Text == "" || txt_UserPsw.Text == "")
{
Response.Write("<script language=javascript>alert('Please input more...')</script>");
}
else if (txt_UserPsw.Text == userPsw)
{
UserInfo user = new UserInfo();
user.UserID = userID;
user.UserName = userName;
user.UserPsw = userPsw;
user.StyleID = int.Parse(styleID);
user.DepartID =int.Parse(departID);
user.Email = email;
Session["UserInfo"] = user;
Response.Redirect("main.aspx");
//Response.Redirect("main.aspx?id=" + userID + "&name=" + userName + "&sty=" + styleID + "&dep=" + departID + "");
}
else
{
Response.Write("<script language=javascript>alert('Please check the ID or PSW...')</script>");
}
}
但是经过调试,始终都无法获取到正确值(尽管输入正确的用户名、密码)。最后经过单步调试,确定是因为在imagebutton1 的Click事件中的txt_UserID.Text始终为"HF",所以在数据库中提取不到数据,而一直报错!
但是为什么txt_UserID的值不采用我们的输入值(ex,HF0001),而一直采用"HF",我们的"HF"可只是在LogIn页面加载时才赋予txt_UserID初值"HF"的啊?百思不得其解。。。
后经过修改,将txt_UserID.Text = "HF"部分注释掉,即可获得想要的结果。可这是Page_Load中的啊,我们做的可是操作提交按钮啊,这,哪跟哪的关系啊???
再后来,经过网络这一巨大资源库,终于得知其缘由。先给出改进的方案(不以损坏原有功能为代价获取想要结果,即"HF"前缀),见代码:
{
//为了获得在每次登录时都可以以HF开头
if(!isPostBack)
{
txt_UserID.Text = "HF";
txt_UserID.Focus();
}
}
对,就这么简单,加一判断语句即可。而就其根本,这就引出本文主题——页面生命周期问题。
页面生命周期概述:
同生物体一样,Asp.Net页面在运行时也经历一个周期。类似的,同生物体的出生、成长、成熟及至死亡的阶段过程类似, Asp.Net页面也执行一系列步骤,其包括初始化、实例化控件、还原和维护状态、运行事件处理程序以及进行呈现。了解页面生命周期非常重要,因为只有了解它,才能在合适的地方书写合适的代码,已达到我们预期的效果。下图示为常规页面的生命周期阶段:
其对应的简化版本为:
1.Page_Init阶段:执行上图开始和页初始化阶段任务。我认为即是页初始化和控件的初始化(赋予其属性初始值);
2.Page_ViewState阶段:对应上述加载项,它的应用场景是PostBack时。即在CLR运行下,将控件的ViewState值赋予控件;
3.Page_Load阶段,即对应Code Behind代码中的Page_Load函数;
4.Page_EventHandler阶段,即对应上述回发事件处理项,它的应用场景也是在PostBack时;
由上页面生命周期的概述,再回过头来看起初问题,便迎刃而解了。
首先,在请求LogIn页面时,没有问题:用户名框出现"HF",此时可以放心填写用户名、密码;
其次,在点击登陆按钮时,在服务器端并不为触发事件中的Redirect而另开小灶,它依然执行着LogIn页面的生成任务,即 Page_Init,Page_ViewState,Page_Load过程,然我们可见我们填写的用户名(ex,HF0001)——其作用范围在Page_Init和Page_ViewState阶段,被Page_Load中的对txt_UserID赋值而再更改为"HF"!这就是原因所在!
最后, 我们即在page_Load中加上回送请求语句,即可避免重赋上无意义的值。
注: 对于上述中的引用到的Page_ViewState,其为服务器控件的状态管理属性,在以后会举例说明