5. ViewState原理
在以上的章节中说明过,只有表单域中有Name的属性元素值才能被传输到服务端。
如果我们想在div中显示一个值进行递增(不要放服务端控件),而div又没有name属性,哪它如何显示自增呢?(纯粹用html元素)
我们可以这样处理一下:
1.在客户端中我们放一个hidden元素,由于它有name值,故可以传递它的name及value到服务端,我们可以把它的value值设置为@value(自行设计),在div中也用@value显示,即<div> @value</div>,让客户端表单处理的页面指向服务端,当服务端得到hidden的值后并加1再把整个客户端页面中的@value替换为自增后的值并渲染给客户端。如下为源代码(模板页):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> </head> <body> <form action="incDiv.ashx"> <input type="hidden" name="back" value="yes" /> <input type="hidden" name="num1" value="@value" /> <div> <label style="color:Red" > @value</label> </div> <br /> <input type="submit" value="自增" /> </form> </body> </html>
第一个hidden是告知服务端是不是postback状态,第二个hidden是传递值,即它的值和div中的值是同步的。
2.服务端处理(一般处理程序)
<%@ WebHandler Language="C#" Class="incDiv" %> using System; using System.Web; public class incDiv : IHttpHandler { public void ProcessRequest (HttpContext context) { context.Response.ContentType = "text/html"; string back=context.Request["back"]; string num="0"; if(back=="yes") { num=context.Request["num1"]; int i = Convert.ToInt32(num); num = (++i).ToString(); }; string path = context.Server.MapPath("IncDiv.htm"); string content = System.IO.File.ReadAllText(path); content = content.Replace("@value",num); context.Response.Write(content); } public bool IsReusable { get { return false; } } }
在客户端的浏览器中直接运行incDiv.ashx即可,不要运行模板页,因为它是模板。
我们在用http工具进行抓包查看时,会发现这些值已被hidden传递到服务端。当我们用asp.net开发时,发现不用这样的操作也可,放个lable,也会显示自增,我们用http抓包工具时也会发现浏览器会发送一些隐藏在报头文件数据传递的服务端,其实这些就是用隐藏元素把值进行了传递,即asp.net中所谓的viewstate,这就是ViewState的原理,但我们在开发互联网时必须部分禁用viewstate,因为它增大流量并加重服务器的负担。在内网或互联网后台可以心情的用ViewState即可。
禁用ViewState有两种方法,一种是禁用单个元素,禁用方法为:
如对textbox的禁用, <asp:TextBox id="aa" EnableViewState="true" runat="server" /> ,当设置EnableViewState 为True时表示可以用,false表是不可用。
另一种禁用是对整个页面的禁用,即要以下的位置:
<%@ Page Language="C#" AutoEventWireup="true" EnableViewState="false" CodeFile="AspIncViewState.aspx.cs" Inherits="AspIncViewState" %>
这样整个页面将不用ViewState
另还有个ViewStateMode特性,它只有在EnableViewState为true时才能用。
Asp.net为什么要用ViewState?
因为浏览器只会提交有Name属性的元素值,像元素的颜色、宽度等属性浏览器并不会传递给服务端,服务端就不可能处理或返回这些值,但客户端是需要这些的,故Asp.net中系统默认会用隐藏元素把相关的信息传递给服务器,这就是Asp.net 的viewstate,它实际是封装了隐藏元素。