用ASP实现Web表单的数据保持(一)
青苹果工作室编译 2000-10-31 10:31:49
如果你使用过Internet Explorer
5,那么你可能已经有过在Web页面中保持一种状态的想法。其实这不是一个新的话题,只不过是一个新术语,它所包含的事情你可能已经在你的Web
站点上做过一段时间了。在我们所关心的范围内,保持的意思就是包含输入值或经用户设置的Web页面在下一次被打开时保持这些上一次数值的能力。
事实上,有些浏览器能自动作到这一点--通常来源于用户选择的选项设置。比如说,当你点Back 按钮重新装载这一页时,Navigator
4 在其默认配置中能够记住你在表单的控制项上所使用的值。但是这些还是不太可靠,最好是有一种可以更加可靠地自动处理这个过程的方法。
用隐藏的表单控制域保持数值
在特定Web 页面之间保持值的常用方法是通过使用嵌入在页面中的HIDDEN 类型控制域来实现。它与一些简单的ASP代码一起使用可以把数值从一页传递到另一页,而不用显示它们。举例说,在一个页面上<
FORM > 上的控制:
< INPUT TYPE="HIDDEN"
NAME="hidThis" VALUE="< % = storedValue
% >" >
可以将数值传递到另一个页面,这个页面使用Request.Form摘取上层页面设置的数据。它可以用来设置一个可见控制域的数值,或者放置在另一个HIDDEN控制域中并传递到另一页。
< INPUT TYPE="TEXT"
NAME="txtThis" VALUE="< % = Request.Form("hidThis")
% >" >
或
< INPUT TYPE="HIDDEN"
NAME="hidNext" VALUE="< % = Request.Form("hidThis")
% >" >
有一个问题是:如果你装载了一个不传递数值的页面从而破坏了这个链条,它就永远丢失了。对此,我们可以用一些更永久和更可靠的办法。
一个更好的办法--ASP Sessions
要存储那些我们想要放置在页面的HTML控制中的数值,ASP Sessions提供了一个很明显的办法。事实上,Sessions对于保存什么都是很有用的--甚至是从一个数据源创建的记录集,或我们想在一个用户Sessions中重复使用的对象引用。当每个用户装载一个global.asa文件作用范围内的ASP页面时,ASP都自动启动一个新的用户Session。global.asa文件的作用范围的含义换句话说就是,装载页面的文件夹包含global.asa文件,或者在这个文件夹中之上的文件夹中包含global.asa文件(距离根目录更近)。
当你遇到一些个别数值时,可以在Session 对象中储存它们,然后再根据需要恢复它们。比如,在一个接收标准HTML页面的<
FORM > 部分所传递的值的ASP页上,可以用下面代码将它们存储到Session 中:
Session("thisValue")
= Request.Form("thisValue")
Session("nextValue")
= Request.Form("nextValue")
... etc ...
然后,包含< FORM >的页面 (它现在必须是一个ASP文件)可以在它装载时恢复这些值:
< INPUT TYPE="TEXT"
NAME="txtThis" VALUE="< % = Session("thisValue")
% >" >
< INPUT TYPE="TEXT"
NAME="txtNext" VALUE="< % = Session("nextValue")
% >" >
但是,这需要一些预先的计划,并要注意Session变量名不被别的页面复制和覆盖。而且它不处理非文本类型的控制域,如选择框或选项按钮。要处理这些控制,当选择框或按钮在装载页面时自动设置时,需要给<
INPUT >元素增加一个CHECKED属性。
在Sessions中使用数组
通过将来自页面的值装入存储在用户Sessions中的数组,我们可以比前面的例子做得更好。并且为了防止变量名的冲突,我们要把页面的名用做Sessions变量的名。这样,只有当我们有多个拥有同样名字的页面时,才需要注意到这个问题。
虽然通过把完整的URL作为session 变量名可以避免这个问题,但是变量名中不能包含斜线,所以必须将斜线转换成其它字符。本文中为了简短起见,我们使用页面名。
但是你要说了,等一等,session对象不能储存数组,只能储存变量。没问题。当我们把一个数组赋给
session 时,这个session 就包含了一个到数组的变量指针。以后我们可以象恢复一个普通变量一样恢复整个数组。当数组被存储到session
中,我们做不到的是在数组中存取单独的条目--我们首先要释放它。这个过程是:
Dim arrVals(1, 1) ‘declare a 2
x 2 element array
arrVals(0, 0) = "this "
‘fill it with values
arrVals(1, 0) = "is "
arrVals(0, 1) = "my "
arrVals(1, 1) = "array "
Session("myarray") =
arrVals ‘and store it in the session
然后我们用下面的代码恢复它。注意开始你不将变量(在本例中是arrVals)声明为数组:
arrVals = Session("myarray")
‘retrieve the array
myString = arrVals(0, 0) &
arrVals(1, 0) & arrVals(0, 1) & arrVals(1, 1)
Response.Write myString ‘gives
"this is my array"
我们的目标是将控制域的值与这些控制的名字储存在一起,存储在一个数组中,这个数组要跟随需要保持数值的页面来命名。换句话说,我们所要寻找的就是:
Dim arrVals(1, 1)
arrVals(0, 0) = "txtFirstname"
arrVals(1, 0) = "James"
arrVals(0, 1) = "txtLastName"
arrVals(1, 1) = "Dixon"
Session("getname.asp")
= arrVals
然后我们恢复它,并填充到控制中,用:
arrVals = Session("getname.asp")
< INPUT TYPE="TEXT"
NAME="txtFirstName" VALUE="< % = arrVals(1,
0) % >" >
< INPUT TYPE="TEXT"
NAME="txtLastName" VALUE="< % = arrVals(1,
1) % >" >
但是这还要求我们计算出哪个数组元素中保存着各个控制域的值。ASP
Request集合的排序不是很整齐--它们中的值通常与页面上的控制顺序不同(在后面你就可以看到有关这个问题的证明)。我们在集合中循环并且填充数组之后,并不能保证各个值会落在数组的什么地方。
Request.Form 集合的内容
所以,我们所要做的是创建一个简单的函数,它以控制域的名称为基础,从数组中为我们恢复正确的值。这还为我们提供了机会,在Request.Form
集合的值不能反映那些在页面中被要求设置为正确值的HTML的地方,处理选择框和按钮的情况。在我们看这个函数之前,先简要回顾一下不同的HTML控制域的名字和值是如何通过Request.Form
集合处理的。下面所显示的页面把控制域的名称作为标题。创建这些控制域的HTML是:
FirstName: < INPUT TYPE="TEXT"
NAME="FirstName" >< BR >
LastName: < INPUT TYPE="TEXT"
NAME="LastName" >
< P >
I enjoy:
< INPUT TYPE="CHECKBOX"
NAME="Swimming" > Swimming
< INPUT TYPE="CHECKBOX"
NAME="Reading" > Reading
< INPUT TYPE="CHECKBOX"
NAME="Eating" > Eating
< P > OtherHobby: < INPUT
TYPE="TEXT" NAME="OtherHobby" ><
BR >
OtherHobby: < INPUT TYPE="TEXT"
NAME="OtherHobby" >< BR >
OtherHobby: < INPUT TYPE="TEXT"
NAME="OtherHobby" >
< P >
I live in:
< INPUT TYPE="RADIO"
NAME="Country" VALUE="America" >
America
< INPUT TYPE="RADIO"
NAME="Country" VALUE="Europe" > Europe
< INPUT TYPE="RADIO"
NAME="Country" VALUE="Elsewhere" >
Elsewhere
< P >
< INPUT TYPE="SUBMIT"
VALUE="Submit" >
< INPUT TYPE="RESET"
VALUE="Reset" >
下面是浏览器的样子,在这里我们可以填入一些值:
当这被发送到服务器,我们可以检查Request.Form集合的内容,并恢复这些值。唯一令人苦恼的地方是,当两个或更多的控制名相同,以那个名字命名的Request.Form集合返回的值本身就是一个值的集合。为了解决这个问题,我们用以下代码来显示控制域的值。
‘loop through the Request.Form collection
For Each varItem in Request.Form
If Request.Form(varItem).count >
1 Then
‘this is itself a collection so
iterate each value
For intLoop = 1 to Request.Form(varItem).count
‘display control name and value
Response.Write varItem & "("
& intLoop & ") = "
& Request.Form(varItem)(intLoop)
& "< BR >"
Next
Else
‘this is a single control item
Response.Write varItem & "
= " & Request.Form(varItem) & "< BR
>"
End If
Next
在上面的表单页面中被出这些值时,可以得到这些结果--注意名字/数值对的顺序与原始页面中控制域的顺序不同。
FirstName = Alex
LastName = Homer
Swimming = on
Country = Europe
Eating = on
OtherHobby(1) = Computers
OtherHobby(2) = Gardening
OtherHobby(3) =
以上显示了每个文本框的名字,以及我们在其中输入的值。但是要注意三个有相同NAME属性的文本框被作为一个集合返回,由我们所输入的值组成--包括空文本框。结果还显示3个选择框中的2个的名字。没被设置(选择)的一个不在Request.Form
集合中放置数值。而且,因为我们不为选择框提供一个值,他们就只返回一个" on " 作为值。
但是这三个选项按钮--有相同的名字--只返回一个值。这就是所选择的选项的VALUE
属性。如果我们不为每一个提供不同的值,Request.Form 集合就会只包含" Country=on
",换句话说就是所有三个选项按钮的名字和值" on "。
|