由于http协议是无状态性的
客户端浏览器在与服务器端进行交互的时候,客户端向服务器端发送请求,服务器响应并处理请求,但由于http无状态性,所以服务器端并不知道上次给了客户端浏览器什么,所以客户端浏览器需要“记住”上次服务器端给予的值(如:input表单元素就是“记忆”到value中,而对于其他的值就要放到隐藏字段中,比如viewstate),下次客户端浏览器再提交请求给服务器的时候(如:请在我原先的宽度基础上再增加10,就要把上次存到隐藏字段中的中再提交给服务器,让服务器“想起”上次给予客户端的值,并再此基础上增加10)。
如果要知道上一次的状态,一个方法是在对浏览器响应结束之前将状态信息保存到页面表单中,下次页面再向服务器发出请求的时候带上这些状态信息,这样服务器就能根据这些状态信息还原上次的状态了,类似于去看病时的病例本。
但是,状态信息保存到隐藏字段中有缺点:加大网站的流量,降低了访问的速度,机密数据保存到表单中会有数据欺骗等安全性问题。
下面举个例子:
Label文本值的自增,和TextBox值的自增,在这两个控件中值的自增就提现出来viewstate的作用
很简单的点击按钮加1的代码
我们查看源文件,发现html源文件里面有个hidden 元素,它的name 属性是“__VIEWSTATE,这里面就是一个viewstate的隐藏元素,里面使用序列化算法将隐藏内容存放到一个字符串中,我们使用ViewStateDecoder工具查看这个viewstate字符串,发现它存储的是label的值,而没有textbox的值
当我们禁用了viewstate之后(enableviewstate="false"),我们发现,label的自增失败了,而textbox的自增不受任何影响,这说明,label需要将值存放到viewstate中,而textbox不需要将值存放到viewstate中。
就想上面我们所说的,viewstate是存储非表单域,非value值的容器,由于textbox解析成Html后就是一个input type=“text” value="",它是有value属性的,所以它的值存放到了value中,不需要用到viewstate 而label解析成html后它实际上是一个span 标签,是没有value属性来给它存放值的,所以它需要使用viewstate来存放它的值,在上述自增的例子中,label需要使用viewstate记住上次服务器返回给它的值,好让下次提交请求给服务器的时候,服务器能够“记忆”起它的值,然后再它的基础上+1,
当然,即使是textbox(input)也只有存放到value中,才能够让服务器“记起”,要传递其它值,比如宽度,大小等,这也需要使用viewstate了。
在讲解viewstate原理中,input(textbox)版本值的自增和div(label)版本值的自增,能很好的阐述这个道理。