在实际项目中,常常需要保存用户信息来简化掉一些不必要的重复动作,提供人性化和智能的交互方式。然而HTTP协议是无状态的,每个新页面请求都是接。ASP.NET提供了保存状态的不同选项,使得状态额可以在客户端或服务器上保存。
要在客户端保存状态,ASP.NET提供了视图状态、cookie和参数选项。因为安全问题,使用这些状态有一些限制。在服务器端可以使用会话对象、全局应用程序状态、缓存和用户配置文件来保存状态。
ASP.NET也提供了一些用于访问状态管理功能的属性。例如,HttpSessionState对象可以在Page类的Session属性中直接访问。也可以使用HttpContext获得HttpSessionState,HttpContext.Current返回活动的HttpContext对象,这个类的Session属性也可以返回HttpSessionState。
下面将分别解析这些不同的状态管理选项。示例使用ASP.NET Web Forms页面及Textbox、Label和Button控件,来演示不同的状态功能。
视图状态
视图状态仅在页面内部可用。只要用户位于同一个页面中,就可以使用视图状态。视图状态在页面中创建隐藏的HTML字段,该字段会发送给服务器,因为它位于<form>标记中。视图状态可以使用Page的ViewState属性来访问,ViewState会返回一个StateBag对象。把一个键值传递给索引器,就可以使用视图状态来读写数据。
在以下示例代码中:
protected void Button1_Click(object sender, EventArgs e) { Label1.Text = string.Format("TextBox1.Text:{0}", TextBox1.Text); Label2.Text = string.Format("ViewState[\"state1\"]{0}", ViewState["state1"]); ViewState["state1"] = TextBox1.Text; }
第一次打开页面时,还没有调用Bbutton1_Click方法,两个标签都显示初始值。把one写入文本框并单击按钮第一次调用Bbutton1_Click方法,就会给服务器发送一个回发。此时,TextBox1.Text属性返回输入的数据,因为第一个Label用这个数据填充,第二个Label只显示消息的第一部分,ViewState["state1"]返回为空。把two写入文本框,第二次单击按钮,则给服务器发送另一个回发,ViewState["state1"]现在返回上一次输入的数据one,TextBox1.Text返回新字符串two。
视图状态使用页面中的隐藏字段来存储:
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJNTAzMzI1MjcyDxYCHgZzdGF0ZTEFA3R3bxYCAgMPZBYEAgEPDxYCHgRUZXh0BRFUZXh0Qm94MS5UZXh0OnR3b2RkAgUPDxYCHwEFFlZpZXdTdGF0ZVsic3RhdGUxIl10d29kZGS/Lx64nbzEp3zavs9xOCFUE+yVx8Z01piL0emNSmVtSA==" />
使用隐藏字段的优点是没有超时,只要页面处于打开状态,就存在隐藏字段,并在下次回发时发送给服务器。如果用户关闭页面,状态就消失了;如果用户切换到另一个页面上,状态也会消失。视图状态的缺点是状态必须在字符串中表示,所有的视图状态数据总是通过网络发送,这可能涉及传输大量数据,降低了性能。
特别地,ASP.NET服务器端控件使用视图状态,服务器端事件模型基于该状态模型,把窗体内容发送给服务器时,窗体会在视图状态中包含文本框的以前值,在文本框中包含当前值。这样,事件机制就可以确定是否为出发变动事件,并调用响应的处理方法。