本文所介紹的應(yīng)用程序是以ASP編程的初學(xué)者為讀者的。雖然這個(gè)例子非常簡(jiǎn)單,但是它對(duì)于那些試圖在線(xiàn)對(duì)他們的雇員、學(xué)生或客戶(hù)進(jìn)行考試的組織是非常有用的。
關(guān)于這個(gè)應(yīng)用程序
我們的應(yīng)用程序中的第一個(gè)界面包含在index.asp 中,由一個(gè)注冊(cè)頁(yè)組成,其中有兩個(gè)輸入域,一個(gè)是用戶(hù)名,另一個(gè)是口令。非會(huì)員要想?yún)⒓涌荚嚨脑?huà)必須要注冊(cè)。這一頁(yè)是初始屏幕,為用戶(hù)提供用戶(hù)名和口令的輸入框。

需要注意的是,這兩個(gè)將要批準(zhǔn)的會(huì)員域應(yīng)該有客戶(hù)機(jī)端的javascript 確認(rèn),以便不把它們作為空白域來(lái)傳遞。
if (theForm.username.value == "")
{
alert("Please enter the \"User Name\"");
theForm.username.focus();
return (false);
}
if (theForm.password.value == "")
{
alert("Please enter the \"Password\"");
theForm.password.focus();
return (false);
}
創(chuàng)建這些域的HTML代碼如下:
< table border="0" cellpadding="0" >
< tr >
< td width="50%" >
< font face="Verdana" size="2" >User Name : < /font >
< /td >
< td width="50%" >
< font face="Verdana" size="2" >< input type=text name=username
size=20 maxlength=50 >< /font >
< /td >
< /tr >
< tr >
< td width="50%" >
< font face="Verdana" size="2" >Password :< /font >
< /td >
< td width="50%" >
< font face="Vedana" size=2 >< input type=password name=password
size=20 maxlength= 50 >< /font >
< /td >
< /tr >
< tr >
< td width="100%" colspan="2" align="center" >
< font face="Verdana" size="2" >< br > < input type="submit" value="Submit" name="B3" >
< input type="reset" value="Reset" name="B4" >
< /font >
< /td >
< /tr >
< /table >
要注意這個(gè)ASP頁(yè)多多少少是一個(gè)HTML頁(yè)面,作為ASP頁(yè)的原因是要顯示錯(cuò)誤信息,例如“錯(cuò)誤的用戶(hù)名或口令或選擇一個(gè)新用戶(hù)名”,或者是需要顯示的其它任何信息。注冊(cè)表單中包含一些個(gè)人信息,如姓名、Email 、口令等。同樣可以從訪(fǎng)問(wèn)者得到關(guān)于年齡、教育程度、職業(yè)等方面的信息。一旦成功的輸入了個(gè)人信息,訪(fǎng)問(wèn)者就成為一名會(huì)員,可以使用站點(diǎn)的其它部分了。根據(jù)應(yīng)用程序的設(shè)計(jì)要求,這些域可以是必須輸入的,也可以不是。
登錄代碼Register.asp
當(dāng)一個(gè)新的訪(fǎng)問(wèn)者注冊(cè)了一個(gè)在線(xiàn)考試時(shí)就顯示這一頁(yè)。它可能會(huì)要求大量的個(gè)人信息,但是在本例中只要求姓名、Email 和口令。表單提交后,用戶(hù)被引領(lǐng)至sendregister.asp。
Sendregister.asp
這一頁(yè)從register.asp 中取得表單域的內(nèi)容,將它們插入數(shù)據(jù)庫(kù)中。要注意用戶(hù)名必須是唯一的。所以,首先查詢(xún)要驗(yàn)證輸入的用戶(hù)名是否已經(jīng)存在。如果是的話(huà),用戶(hù)被重新引回register.asp 頁(yè),并被要求選擇另一個(gè)用戶(hù)名。如果用戶(hù)名是新的,輸入的內(nèi)容就被傳遞給數(shù)據(jù)庫(kù)。
sql_findmember = "select count(*) from loginuser where username = " & username &""
Set RS_findmember = Application("Conn").Execute(sql_findmember)
If RS_findmember(0) < > 0 Then
Session("message") = "THE ENTRY HAD BEEN INSERTED EARLIER .. Please try another log in name"
response.redirect "register.asp"
End If
If RS_findmember(0) = 0 Then
sql_insert = "insert into loginuser (username,useremail,password) _
values(" & username & "," & useremail & ", " & pwd &") "
Set RS_insert = Application("Conn").Execute(sql_insert)
Session("message") = "THE ENTRY HAS BEEN INSERTED .. Thank You"
response.redirect "index.asp"
End If
這樣,如果RS_findmember(0) 返回的值是0,就表示用戶(hù)名在數(shù)據(jù)庫(kù)中不存在,名字就被輸入了。會(huì)員就可以使用站點(diǎn)的其它部分了。反之,如果RS_findmember(0) 返回的值大于0,用戶(hù)就被引導(dǎo)回注冊(cè)主頁(yè),并被要求填寫(xiě)一個(gè)新的用戶(hù)名。
還要注意,在向數(shù)據(jù)庫(kù)中插入數(shù)據(jù)之前有一些事情需要警惕。替換函數(shù)用來(lái)確保當(dāng)訪(fǎng)問(wèn)者鍵入了"",就需要用代替。
username = replace(request.form("txt_name"),"","")

Checkuser.asp
在應(yīng)用程序的開(kāi)始,訪(fǎng)問(wèn)者鍵入了他們的口令之后,他們的細(xì)節(jié)被指向了一頁(yè),如sendregister.asp,來(lái)檢驗(yàn)一下具體的用戶(hù)名和口令在數(shù)據(jù)庫(kù)中是否存在。
sql_check = "select count(*) from loginuser where username =" & _
username &" and password = " & useremail &""
Set RS_check = Application("Conn").Execute(sql_check)
If RS_check(0) < > 0 Then
Session("username") = request.form("username")
response.redirect "default.asp"
End If
If RS_check(0) = 0 Then
Session("error") = "WRONG USER NAME OR PASSWORD"
response.redirect "index.asp"
End If
sql命令檢查一個(gè)特定的用戶(hù)是否已經(jīng)注冊(cè)了。如果返回值為0,就表明用戶(hù)名或email 無(wú)效,將用戶(hù)引導(dǎo)回注冊(cè)頁(yè)。如果是會(huì)員,就被引導(dǎo)到default.asp 頁(yè)。這一次又用到了替換函數(shù),以保證如果會(huì)員鍵入了‘ (單引號(hào)),就要用 (雙引號(hào))來(lái)替換。
username = replace(request.form("username"),"","")
useremail = replace(request.form("password"),"","")
選擇一個(gè)測(cè)驗(yàn)Default.asp
一旦成功登錄,就出現(xiàn)第二個(gè)界面,提供會(huì)員可以選擇的測(cè)驗(yàn)科目的列表。在本例中,我們有HTML 和DHTML ,當(dāng)然可以增加表格以提高主題數(shù)。Default.asp 要求表格安裝一個(gè)下拉菜單,其中包含主題的列表。查詢(xún)數(shù)據(jù)庫(kù),從試卷的表格中搜集兩個(gè)域。
sql_papers = "select *id, topic from paper sort order by topic asc"
SET RS_papers = Application("Conn").Execute(sql_papers)
為了在下拉菜單中顯示結(jié)果,使用以下代碼:
SELECT size=1 name=select1 onchange="msec(document.form1._
select1.options[document.form1.select1.selectedIndex].value);" >
< option value="0" >Select the examination
< %Do while not RS_papers.EOF% >
< option value="< %=RS_papers("id")% >" >< %=lcase(RS_papers("topic"))% >< /OPTION >
< %
RS_papers.MoveNext
Loop
% >
msec函數(shù)在X值的基礎(chǔ)上調(diào)用 redirect.asp,把查詢(xún)字符串: ?x 的值作為下拉菜單中被選擇的項(xiàng)的值。
function msec(x)
{if (x==0)
{ alert("Please select any one of the Examinations")
}
else
{ location. f="redirect.asp?section=" + x
}
}

Redirect.asp
這一頁(yè)將用戶(hù)送到實(shí)際生成題目和選項(xiàng)的ASP頁(yè)。如果數(shù)據(jù)庫(kù)中沒(méi)有所選擇的特定主題的任何題目,就顯示錯(cuò)誤信息和返回連接。
首先:
id = Request.QueryString ("section")
調(diào)用查詢(xún)字符串部分,將值存入變量 id中。
然后:
SQL = "select tbl_name from paper where id="&id
Set RS = Application("Conn").Execute(SQL)
subject= RS(0)
MyString = Split(subject,"tbl",-1,1)
SQL聲明傳遞試卷表格中的域名 table_name 。結(jié)果存儲(chǔ)在subject中。進(jìn)一步分離變量subject,將其存儲(chǔ)在MyString中。Split 函數(shù)用來(lái)在客戶(hù)端顯示測(cè)驗(yàn)名,是為了看起來(lái)效果更好。
IF RS_subject.BOF AND RS_subject.EOF Then
Response.Write Online " & MyString(1) & Test is still to be launched. Come back _
later < a href=default.asp >BACK< /a >"
Else
Response.Redirect ("exam.asp?section="&id )
End If
如果以上查詢(xún)產(chǎn)生了結(jié)果,就表示會(huì)員所選擇的科目中有題目,可以進(jìn)行在線(xiàn)考試。如果特定部分還在創(chuàng)建中,就告訴訪(fǎng)問(wèn)者稍后再回來(lái)進(jìn)行考試。這是主考者的特殊興趣,因?yàn)闀?huì)員能夠知道在前面的屏幕上下拉菜單所提供的科目哪些是懸而未決的。這樣,如果這個(gè)部分有題目和相應(yīng)的選項(xiàng),這一頁(yè)就被重新引導(dǎo)到exam.asp 頁(yè),其中包含著實(shí)際的題目。
測(cè)驗(yàn)代碼
Exam.asp 提供一系列的題目和以單選按鈕為格式的選項(xiàng)。為了使測(cè)驗(yàn)更具挑戰(zhàn)性,還要有時(shí)間限制。我設(shè)置了一個(gè)裝載時(shí)自動(dòng)啟動(dòng)的時(shí)鐘,將其時(shí)間設(shè)為20秒。剩余的時(shí)間在屏幕底部的狀態(tài)窗口中顯示。時(shí)間因素同題目個(gè)數(shù)一樣可以改變。為了在每次會(huì)員想要參加考試時(shí),都從數(shù)據(jù)庫(kù)中選擇不同的題目,我使用了隨機(jī)函數(shù)。在數(shù)據(jù)庫(kù)中,題目的個(gè)數(shù)固定為10個(gè),每次會(huì)員回答5個(gè)問(wèn)題。所有的題目都一起顯示出來(lái),然后開(kāi)始計(jì)時(shí)。以下代碼是計(jì)時(shí)器的函數(shù):
< script language="javascript" >
var ck=0;
var tf=0;
var timeUp=0;
var timeLeft=0;
var tcount=0;
TimerFunc();
function TimerFunc() {
tf=window.setTimeout("TimerFunc();",1000);
tcount++;
timeLeft=20 - tcount;
window.status = timeLeft + " Seconds remaining";
}
< /script >
要注意,沒(méi)有時(shí)間限制的測(cè)驗(yàn)是沒(méi)有樂(lè)趣的。
這頁(yè)的查詢(xún)是這樣的:
id = Request.QueryString ("section")
session("id") = id
sql_tblname = "select tbl_name from paper where id="&id
Set RS_tblname = Application("Conn").Execute(sql_tblname)
subject= RS_tblname(0)
MyString = Split(subject,"tbl",-1,1)
查詢(xún)字符串存儲(chǔ)在一個(gè) session("id")中, 按順序啟動(dòng)查詢(xún)。這個(gè)SQL聲明的目的是從試卷表格中找到表格名。使用split 函數(shù)的目的是從結(jié)果中去掉tbl。(我使用了表格名前加tbl前綴的命名慣例)。一旦找到了表格名,就開(kāi)始了向指定表格的查詢(xún)。為了使應(yīng)用程序更有意思,我使用了隨機(jī)函數(shù),生成從1到10之間的任意數(shù)字。這些數(shù)字用來(lái)從指定的科目表格中選取id:
sql_details = "select a.id, a.question, a.choice1, a.choice2,a.choice3, " &_
" a.choice4 from " & subject & " a where a.id="&MyArray(Counter)
在這個(gè)查詢(xún)中,id,question、 choice1、 choice2、 choice3、 choice4 都是科目表格中的域名。
MyArray(Counter) 是已經(jīng)生成的隨機(jī)數(shù)字。

測(cè)驗(yàn)結(jié)束后,結(jié)果被存儲(chǔ)起來(lái)并被增加到數(shù)據(jù)庫(kù)的細(xì)節(jié)表格中。這樣會(huì)員就能看到測(cè)驗(yàn)的結(jié)果了。(在本例中,我只保留了科目的一個(gè)記錄和百分制的分?jǐn)?shù)。還可以有一個(gè)時(shí)間-日期標(biāo)志。)
記錄結(jié)果Result.asp
這一頁(yè)的主要目的是顯示結(jié)果,同時(shí)將這些結(jié)果插入數(shù)據(jù)庫(kù)以備將來(lái)參考。
for each item in Request.Form
sql_check = "select Count(*) from "&subject&" where answer =" & Request.Form(item) & ""
Set RS_check = Application("Conn").Execute(sql_check)
if RS_check(0) > 0 then
result = result + 1
end if
next
變量result中存儲(chǔ)了結(jié)果。
百分?jǐn)?shù)是從result中算出來(lái)的,如下所示:
percent = round(( 100 * result )/count)
要將這個(gè)結(jié)果存儲(chǔ)在數(shù)據(jù)庫(kù)中,執(zhí)行以下查詢(xún):
sql_id = "select id from loginuser where username=" & Session("username") &""
Set RS_id = Application("Conn").Execute(sql_id)
id= RS_id(0)
SQL_insert = "insert into details (ref_id,subject,score) values(" & id & "," _
& subject & ", " & percent &") "
Set RS_insert = Application("Conn").Execute(SQL_insert)
View.asp
觀看模塊檢查會(huì)員是否以前曾經(jīng)進(jìn)行過(guò)在線(xiàn)考試。如果是的話(huà),將用戶(hù)引導(dǎo)到viewrecord.asp。如果沒(méi)有的話(huà),顯示相應(yīng)的信息。
sql_id= "select id from loginuser where username=" & Session("username") &""
Set RS_id = Application("Conn").Execute(sql_id)
id= RS_id(0)
sql_count = "Select count(*) from details where ref_id = " & id &""
Set RS_count = Application("Conn").Execute(sql_count)
If RS_count(0) < > 0 Then
response.redirect "viewrecord.asp"
End If
If RS_count(0) = 0 Then
Session("noview") = "NO ONLINE EXAMINATIONS HAVE BEEN GIVEN"
response.redirect "default.asp"
End If
Viewrecord.asp
Viewrecord.asp頁(yè)使會(huì)員能夠觀看一些他們的細(xì)節(jié)信息。查詢(xún)?nèi)缦拢?br>sql_details = "Select *subject, score from details where ref_id = " & id &""
Set RS_details = Application("Conn").Execute(sql_details)
結(jié)果是用一個(gè)簡(jiǎn)單的表格格式來(lái)顯示的。

請(qǐng)注意,我并沒(méi)有將會(huì)員可以進(jìn)行一個(gè)主題的考試次數(shù)限制為一次。同一個(gè)主題考試可以進(jìn)行任意次。