用ASP实现Web表单的数据保持(三)
青苹果工作室编译 2000-10-31 10:25:45
取得和使用Session 值
好,现在我们已经安全地包装好了我们的控制域值并且把它们存储在用户Session 中。由于每个用户都有唯一的Session
,这个Session 可以维持到他们关闭浏览器或不从服务器装载页面后20分钟,只有这个用户可以看到和使用他们输入的值。这些值被安全地存储在服务器内存中,而不是象我们使用HIDDEN
类型控制来保存这些值时那样,随着每个页面请求频繁地在客户机和服务器之间来回发送。
事实上,可以用ASP的Session.Abandon 方法来中断一个Session,而通过使用Session.Timeout或编辑注册文件也可以修改timeout
。如果用户装载一个当前global.asa 文件范围以外的页面,如它的文件夹或它的其中一个子文件夹--值也会超出范围。
我们例子中的页面aspstateform.asp 证明恢复和使用存储在一个session
中的动态数组里的值很简洁并且可以反复使用。这个页面所包含的ASP代码首先获取当前页面的名字,然后用它从session对象中恢复恢复一个动态数组。
'get the name of the current page
strScriptName = Request.ServerVariables("SCRIPT_NAME")
strScriptName = Mid(strScriptName,
InstrRev(strScriptName, "/") + 1)
'retrieve the array from the Session
variables
arrVals = Session(strScriptName)
这样我们就解决了根据需求从数组中恢复个别控制域值的问题。我们所选择的方法是在页面中使用ASP的一个定制函数。这个函数的名字是GetSavedValue
,下面就来讲解它。
GetSavedValue 函数
给出了页面上的一个控制名,GetSavedValue 就返回一个文本字符串,这个字符串就是将控制设置成与最后一次提交给服务器相同的状态所要求的值。这是通过从存储的数组中提取值来完成的。但是我们已经发现要将选择框和选项按钮分开处理,要给函数增加第二个参数。这是一个字符串值,我们将它与数组中存储的值进行匹配。
Function GetSavedValue(strControlName,
strMatchValue)
我们需要做的第一件事是要查看我们是否确实得到了一些值,如果是的话,有多少值。如果这一页是在一个session中第一次被装载,那么在Session
对象中就不会有任何为它保存的数组。如果我们试图用UBound函数来得到数列的大小,就会得到一个错误。代码用On
Error Resume Next 来抑制错误信息,然后查看Err 对象看看是否真的发生了错误。如果是就退出。注意我们如何指明希望得到哪一维的大小--在本例中是第二维。如果我们忽略了这个参数,按照默认设置,UBound
函数就会返回第一维的大小。
On Error Resume Next
'find the number of values in the
array
intValCount = UBound(arrVals, 2)
'if there is no array stored in
the Session an error
'will have been generated by the
UBound function
If Err.Number < > 0 Then
Exit Function
如果我们得到了这个值,那么现在就一定要有一个数组。我们在第一维中存储的控制名中循环,直到找到函数中第一个参数提供的控制名相匹配的。如果找到了,就要寻找一下,看看在函数的第二个参数中是否提供了一个“匹配值”,--如果是,我们就知道这是一个选择框或选项按钮。在这种情况下,我们就将“匹配值”与数组中第二维的值比较(存储的控制域的VALUE),如果它们相同就返回"
CHECKED ”,如果不同就返回一个空字符串。同时,如果没有提供第二个参数,我们就简单地返回数列中第二维的值。
'return the value for a given control
name
For intLoop = 0 To intValCount
'see if the name of the control
is in the array
If LCase(arrVals(0, intLoop)) =
LCase(strControlName) Then
'see if we have to match a particular
value
'(for use with a check box or
an option button)
If strMatchValue < > ""
Then
'see if the value does match
that specified
If LCase(strMatchValue) = LCase(arrVals(1,
intLoop)) Then
GetSavedValue = "CHECKED"
Else
GetSavedValue = ""
End If
Else
'just return the value from the
array
GetSavedValue = arrVals(1, intLoop)
End If
Exit Function
End If
Next
End Function
在两个比较测试中,我们的检查与HTML语法是大小写不敏感的。如果需要大小写敏感,可以去掉LCase
函数调用。
使用GetSavedValue 函数
GetSavedValue 函数的结果是控制域值,或者--如果我们指明是第二个参数的匹配值的话--是字符串
"CHECKED" 或空字符串。我们可以用它预先填充我们的表单页面上的所有控制域值。以下是包含HTML控制域的部分:
< FORM ACTION="aspstate.asp"
METHOD="POST" >
FirstName: < INPUT TYPE="TEXT"
NAME="FirstName"
VALUE="< % = GetSavedValue("FirstName",
"") % >" >
< BR >
LastName: < INPUT TYPE="TEXT"
NAME="LastName"
VALUE="< % = GetSavedValue("LastName",
"") % >" >
< P >
I enjoy:
< INPUT TYPE="CHECKBOX"
NAME="Swimming"
< % = GetSavedValue("Swimming",
"on") % > > Swimming
< INPUT TYPE="CHECKBOX"
NAME="Reading"
< % = GetSavedValue("Reading",
"on") % > > Reading
< INPUT TYPE="CHECKBOX"
NAME="Eating"
< % = GetSavedValue("Eating",
"on") % > > Eating
< P >
OtherHobby: < INPUT TYPE="TEXT"
NAME="OtherHobby"
VALUE="< % = GetSavedValue("OtherHobby(1)",
"") % >" >
< BR >
OtherHobby: < INPUT TYPE="TEXT"
NAME="OtherHobby"
VALUE="< % = GetSavedValue("OtherHobby(2)",
"") % >" >
< BR >
OtherHobby: < INPUT TYPE="TEXT"
NAME="OtherHobby"
VALUE="< % = GetSavedValue("OtherHobby(3)",
"") % >" >
< P >
I live in:
< INPUT TYPE="RADIO"
NAME="Country" VALUE="America"
< % = GetSavedValue("Country",
"America") % > > America
< INPUT TYPE="RADIO"
NAME="Country" VALUE="Europe"
< % = GetSavedValue("Country",
"Europe") % > > Europe
< INPUT TYPE="RADIO"
NAME="Country" VALUE="Elsewhere"
< % = GetSavedValue("Country",
"Elsewhere") % > > Elsewhere
< P >
< INPUT TYPE="SUBMIT"
VALUE="Submit" >
< INPUT TYPE="RESET"
VALUE="Reset" >
< /FORM >
文本框控制域
你可以看到我们在没有第二个参数的情况下,用这个函数填充一个文本控制:
FirstName: < INPUT TYPE="TEXT"
NAME="FirstName" VALUE="< % = GetSavedValue("FirstName",
"") % >" >
当它到达客户机,将会有文本值插入,例如:
FirstName: < INPUT TYPE="TEXT"
NAME="FirstName" VALUE="Alex" >
同样对OtherHobby 文本框也适用,但是这次它们是一个集合的成员,所以
我们必须指明NAME和列数:
OtherHobby: < INPUT TYPE="TEXT"
NAME="OtherHobby" VALUE="< % = GetSavedValue("OtherHobby(1)",
"") % >" >
选择框控制域
对于选择框控制,我们将控制名作为第二个参数提供给函数。在我们的例子中,我们不必为选择框指明VALUE 属性,所以我们把"
on " 当作匹配值。这是将要放在Request.Form 集合中的值,于是在我们的存储值数组中:
< INPUT TYPE="CHECKBOX"
NAME="Swimming" < % = GetSavedValue("Swimming",
"on") % > >
并且,由于当有第二个参数提供时,我们的函数返回" CHECKED
"或空字符串,我们可以预见结束时客户机寻找一些东西,如下:
< INPUT TYPE="CHECKBOX"
NAME="Swimming" CHECKED >
选项按钮控制域
选项按钮工作的方式与选择框大致相同。但是必须为它们提供一个VALUE属性,这样就可以破译出来哪个选项被选中。要记住有相同NAME
的选项按钮的完整设置在Request.Form 集合中只提供一个单一值。所以不需要在第一个参数NAME中增加按钮的列数,但是在第二个参数中必须使用VALUE。
< INPUT TYPE="RADIO"
NAME="Country" VALUE="Europe" < %
= GetSavedValue("Country", "Europe")
% > > Europe
如果选择的地方是America,结果就是:
< INPUT TYPE="RADIO"
NAME="Country" VALUE="America" CHECKED
> America
这是全部需要做的
如果你尝试了样本页面,你可以看到我们得到了希望的结果。在当前用户session 持续的过程中,每个控制域值都正确地保持了。如果你还提供了浏览器的第二个版本,你会发现每个都单独保持它自己的值,因为它们都拥有自己的Session
对象。每次< FORM > 被提交,在那个session 过程中储存在动态数组中的值用表单中的新值更新。
如果你修改了值,点击了Reset 而没有提交表单,最后的值就会被恢复。这是因为HTML的Reset
控制将控制的值恢复成原始值--在这种情况下在页面中用ASP代码事先调整值。当然,当< FORM >
和处理< FORM > 中的值的代码在同一页上时这一技术就不能使用,这是没有道理的,也就是说这种情况是表单将页面提交回它自己的情况。
如果你在许多页面中都使用这个技术,你也许愿意考虑一些其它选择。这当然值得将创建数组并把它存储在session中、GetSavedValue
函数以及与恢复数列相关的代码提升到'include' 文件中。用一个SSI #include 指令可以轻易地把这些插入任何页面中。
你也许还愿意考虑创建一个Active Server 组件,它可以完成同样的任务,并且可以用
Server.CreateObject 声明插入适当的页面中。虽然这可能会导致一个更高的服务器负载(因为例示组件的需要),却可以提供更好的性能,因为组件在执行中比编译的ASP代码效率更高。
|