6.4 ViewState对象
ViewState对象又称为“视图状态”,用于维护自身窗体的状态。当用户请求ASP.NET网页时,ASP.NET将ViewState封装为一个或多个隐藏的表单域传递到客户端。
6.4.1 ViewState中的键值对
ViewState是由ASP.NET框架管理的一个隐藏的窗体字段。当ASP.NET执行某个页面时,该页面上的ViewState值和所有控件将被收集并格式化成一个编码字符串,然后被分配给隐藏窗体字段的值属性(即<input type=hidden>)。由于隐藏窗体字段是发送到客户端页面的一部分,所以ViewState值被临时存储在客户端的浏览器中。如果客户端选择将该页面回传给服务器,则ViewState字符串也将被回传。
ViewState提供了一个ViewState集合(Collection)属性。该集合是集合(Collection)类的一个实例,集合类是一个键值集合,开发人员可以通过键来为ViewState增加或者去除项。例如下面的代码:
上面这句代码含义是把一个整数88赋值给ViewState集合,而且给它一个键名Count来标识。如果当前ViewState集合里没有键名Count,那么一个新项就自动添加到ViewState集合里;如果存在键名Count,则与该键名Count对应的值就会被替换。
在ViewState集合里,利用键名可以访问到与键名对应的值,这是键值集合的特性。ViewState集合里存储的是对象(Objects),因此它可以用来处理各种数据类型。下面代码就是从ViewState集合里取得整型数据的示例代码:
6.4.2 ViewState中的安全机制
查看一个Web页面的源文件,就会看到存储的ViewState。其内容可能如下:
以上代码就是ViewState的窗体字段,ViewState的信息是存储在属性value中的。由于属性value值是不可读的,大多数人可能就认为存储在ViewState里的信息是被加密过的,然而事实上并非如此,在以上代码中所看到的value值只是一个经过Base64(一种内容传送编码技术)编码过的字符串。别人可以利用反向工程技术在几秒钟内就把经过Base64编码的字符串变为可读的字符串,从而查看到ViewState中存储的信息。
如果想要使ViewState变得更加安全的话,可以有两种选择。
1.采用哈希编码技术
哈希编码技术被称为是一种强大的编码技术。其算法思想是让ASP.NET检查ViewSte中的所有数据,然后通过散列算法(在密钥值的帮助下)把这些数据编码。该散列算法产生一段很短的数据信息,即哈希代码,然后把这段代码加在ViewState信息后面。
页面被回传后,ASP.NET检查ViewState的数据信息,使用同样步骤重新计算哈希代码,核查计算出来的编码信息是否与存储在ViewState里的哈希代码相匹配。如果有用户更改了ViewState里存储的信息,ASP.NET就会产生一段不能相匹配的新的哈希代码,此时ASP.NET就会拒绝页面完全回传。
哈希代码的功能实际上是默认的,所以如果编程人员希望有这种功能,不需要采取额外的步骤。但有时开发商选择禁用此项功能,以防止出现这样的问题:在一个网站系统中不同的服务器(一个大型的网站通常有很多台服务器)有不同的密钥。为了禁用哈希代码,可以使用在Web.config文件中的<Pages>元素的enableViewStateMac属性,示例代码如下:
2.ViewState加密
尽管使用了哈希代码,ViewState信息依然能够被用户阅读到,很多情况下这是完全可以接受的。但是如果ViewState里包含了需要保密的信息,就需要采用ViewState加密。可以设置单独的某一页面采用ViewState加密,代码如下:
也可以在Web.Config文件为整个网站设置采用ViewState加密,代码如下:
当在ViewState里添加很多信息时,属性value的值就会变得很长,这样就会影响页面打开的速度,所以有时希望禁用个别控件的视图状态,这时就可以通过修改控件的EnableViewStated的属性来改变视图状态。如果不想逐个修改控件,也可以禁用整个页面的视图状态。通过修改Page指令的EnableViewState属性来达到该效果。
6.4.3 存储自定义对象
在ViewState里可以存储自定义的对象,就像在ViewState里存储数值和字符串类型一样容易。然而,为了在ViewState里贮存该对象,ASP.NET技术必须能够把该对象转化成一种字节流,使它可以添加到页面的隐藏输入字段的后面,这一过程被称为“序列化”。如果对象是不能序列化的,当开发人员试图把这样的对象放在ViewState里,就会出现错误。
为了使对象序列化,编程人员需要在类定义之前加一个Serializable属性。例如一个简单雇员类的定义的代码如下:
上面的代码中第1行对雇员类进行序列化后它就可以被存储在ViewState里面。第2行~第8行封装了一个自定义的雇员类。
从ViewState里取回数据时的代码如下:
以上代码中第1行声明一个Employee对象e,第2行从ViewState里取回一个雇员对象。
6.4.4 ViewState对象的使用
前面介绍了ViewState对象的概念以及它的常用方法和属性。本节通过示例来演示ViewState对象在实际中的使用。
【实例6-4】ViewState对象的使用
在网站中存在着不同的用户,各自有不同的权限,登录后可以进入页面也就不同。本例在用户登录时利用ViewState对象记录登录用户的类别,然后根据不同的类别登录实现自动的导航功能。
01 启动Visual Studio 2012,创建一个ASP.NET Web空应用程序,命名为“实例6-4”。
02 在“实例6-4”中创建一个名为Default.aspx的窗体。
03 单击网站的目录下的Default.aspx文件,进入“视图编辑”界面,打开“源视图”,在编辑区中<form></form>标记之间编写如下代码:
上面的代码中第1行和第3行分别添加两个文本框服务器控件TextBox1和TextBox2。第4行添加一个按钮服务器控件Button1并设置其单击事件为Click。
04 单击网站目录下的Default.aspx.cs文件,编写关键代码如下:
上面的代码中第1行定义了一个只读的静态变量的字符串数组,保存系统中已经注册的用户的两种类型admin和user。第2行定义了一个usertype方法,参数是用户类型。第3行~第9行判断用户类型,如果存在于注册的用户中,则返回一个给定的整数。第10行处理按钮控件的单击事件Click。第11行和12行获得用户输入的值。第13行将用户类型保存到ViewState中。第14行~第21行使用switch-case语句判断ViewState中的值,并根据不同的值,跳转到不同用户类型的页面。如果没有存在该种类型,给出错误的提示。
05 在“实例6-4”中分别添加一个Admin.aspx页面和一个User.aspx页面。然后在Admin.aspx.cs和User.aspx.cs文件中添加如下代码:
上述代码第1行处理Page页面的加载事件Load。第2行通过Request对象的QueryString属性获得传递进来的用户类型。第3行在页面显示“用户类型欢迎您”的信息。
06 按快捷键Ctrl+F5运行程序,在显示的如图6-8所示的登录页面中输入用户类型admin和密码,单击“登录”按钮,跳转至如图6-9所示的Admin.aspx页面。
图6-8 运行结果1
图6-9 运行结果2
如果在登录页面中输入用户类型user和密码,单击“登录”按钮。页面会跳转至User.aspx,显示“admin,欢迎您!”,如果输入不存在的用户类型,单击“登录”按钮,会出现如图6-10所示的提示对话框。
图6-10 运行结果3
共有条评论 网友评论