之前几天做了B/S结构的在线考试系统,还有不完善的地方,在此做总结。
该系统由学生选择每一章节的题目数量,然后从数据库中选取选择的数量题目并显示出来进行考试。还要验证图片字段是否有图片,有则显示。
1:使用ORDER BY NEWID()函数随机抽取试题
2:利用控件的视图状态完成随机提取的数据库题目不刷新
因为抽取的试题为随机试题,而且在页面加载的时候提取,这样就涉及如果在加载事件里面验证是否第一次加载的时候,如果不验证,则每次用事件发生时试题都会变化,而验证了则不创建控件的情况。
在查看学习了相关内容后决定用控件的视图状态功能解决上述问题
protected void Page_Load(object sender, EventArgs e) { lblEndtime.Text = "考试时间为90分钟,每小题1分,.您共选择了" + Session["total"].ToString() + "题。考试已用时:"; lblStuNum.Text = Session["ID"].ToString(); lblStuName.Text = Session["name"].ToString(); lblStuSex.Text = Session["sex"].ToString(); lblStuKM.Text = "[" + Session["KM"].ToString() + "]" + "考试试题"; //string num = Request.QueryString["num"]; string leibie = Session["KM"].ToString();//章节 if (Session["KM"].ToString() == "经编") {//如果用户选择不限 name = "lblKmW"; num = "txtNumW"; } else { name = "lblKmK"; num = "txtNumK"; } if (!IsPostBack) { int i = 1;//第几题 for (int x = 1; x < 13; x++)//13个章节 { string sql = ""; string Name = name + x.ToString(); string Num = num + x.ToString(); sql = "select top " + Session[Num] + " * from tblwarpknitting where 类别='" + Session[Name].ToString() + "' and 类别 <> '不限' order by newid() "; //string sql = "select top " + num + " * from tblwarpknitting where 类别=" +leibie + " and 类别 <> '不限' order by newid() "; SqlConnection conn = BaseClass.DBCon(); conn.Open(); SqlCommand cmd = new SqlCommand(sql, conn); SqlDataReader sdr = cmd.ExecuteReader(); while (sdr.Read()) { Literal littxt = new Literal();//题目 Literal litti = new Literal();//换行 littxt.ID = "littxt" + i.ToString(); litti.ID = "litti" + i.ToString(); RadioButtonList cbk = new RadioButtonList();//选项 cbk.ID = "cbk" + i.ToString(); System.Web.UI.WebControls.Image image = new System.Web.UI.WebControls.Image();//图片 image.ID = "pic" + i.ToString(); image.Visible= false; Panel1.Controls.Add(littxt); Panel1.Controls.Add(cbk); Panel1.Controls.Add(image); Panel1.Controls.Add(litti); littxt.Text = i.ToString() + "、" + Server.HtmlEncode(sdr["题目"].ToString()) + "<br><Blockquote>"; litti.Text = "</Blockquote>"; cbk.Items.Add("A. " + Server.HtmlEncode(sdr["选择1"].ToString())); cbk.Items.Add("B. " + Server.HtmlEncode(sdr["选择2"].ToString())); cbk.Items.Add("C. " + Server.HtmlEncode(sdr["选择3"].ToString())); cbk.Items.Add("D. " + Server.HtmlEncode(sdr["选择4"].ToString())); cbk.Font.Size = 11; for (int j = 1; j <= 4; j++) { cbk.Items[j - 1].Value = j.ToString(); } Ans += sdr[7].ToString();//正确答案 ///TOGO Session["Ans"] = Ans;//正确答案 if (sdr["图片"] != DBNull.Value) { //ShowPic(i, sdr["题号"].ToString(),Panel1); //System.Web.UI.WebControls.Image image = new System.Web.UI.WebControls.Image(); //image.ID = "pic" + i.ToString(); image.Visible = true; image.ImageUrl = "getbmp.aspx?ID=" + sdr["题号"].ToString(); Response.Write("<br />"); } tiHao[i - 1] = int.Parse(sdr["题号"].ToString()); i++; tNUM++; } sdr.Close(); conn.Close(); Session["a"] = 1; } } else { int total = int.Parse(Session["total"].ToString()); for (int i = 1; i <= total; i++) { Literal littxt = new Literal(); littxt.ID = "littxt" + i.ToString(); Literal litti = new Literal(); litti.ID = "litti" + i.ToString(); RadioButtonList cbk = new RadioButtonList(); cbk.ID = "cbk" + i.ToString(); System.Web.UI.WebControls.Image image = new System.Web.UI.WebControls.Image();//图片 image.ID = "pic" + i.ToString(); Panel1.Controls.Add(littxt); Panel1.Controls.Add(cbk); Panel1.Controls.Add(image); Panel1.Controls.Add(litti); } } }
在验证了页面不是第一次加载之后只需创建和之前完全一样的控件树并赋予相同的ID,则ASP.NET自动填充控件的内容。
3:使用js完成考试计时功能
<script language="javascript" type="text/javascript"> <!-- var sec=0; var min=0; var hou=0; flag=0; idt=window.setTimeout("ls();",1000); function ls() { sec++; if(sec==60){sec=0;min+=1;} document.getElementById("lbltime").innerText=min+"分"+sec+"秒"; idt=window.setTimeout("ls();",1000); if(min==90) { document.getElementById("btnsubmit").click(); } } function stop() { window.clearTimeout(idt); sec = 0; }
90分钟后强制交卷。
4:点击交卷后显示分数并显示正确答案。
protected void btnsubmit_Click(object sender, EventArgs e) { ClientScript.RegisterStartupScript(ClientScript.GetType(), "myscript", "<script>stop();</script>");//停止计时 int total = int.Parse(Session["total"].ToString()); string msc = ""; int StuScore = 0; string rightAns = ""; for (int i = 1; i <= total; i++) { //string strsql = "select * from tblwarpkintting where 题号 = " + tiHao[i] + "and 类别 = " + Session["Name"].ToString(); //显示正确答案 msc = ""; RadioButtonList list = (RadioButtonList)Panel1.FindControl("cbk" + i.ToString()); if (list != null) { if (list.SelectedValue.ToString() != "") { msc = list.SelectedValue.ToString(); } else { msc = "0"; } Ans = Session["Ans"].ToString(); if (msc.Equals(Ans.Substring(i-1, 1))) { StuScore += 1;//学生分数 } else { rightAns = ""; switch (int.Parse(Ans.Substring(i-1, 1))) { case 1: rightAns = "A"; break; case 2: rightAns = "B"; break; case 3: rightAns = "C"; break; case 4: rightAns = "D"; break; } list.Items.Add("正确答案为:" + rightAns); list.ForeColor = Color.Red; } } } this.lblResult.Text = StuScore.ToString(); this.lblkm.Text = Session["KM"].ToString(); this.lblnum.Text = Session["ID"].ToString(); this.lblname.Text = Session["name"].ToString(); btnsubmit.Visible = false; //Session["Sans"] = msc;//考生答案 }
遇到问题:
1:数据库显示图片问题
因为数据库中保存了2进制图片格式,在使用方法读取时有时候image控件会显示一个小叉叉,暂不知原因。
protected void Page_Load(object sender, EventArgs e) { int id = int.Parse(Request.QueryString["ID"]); SqlConnection userConnection = BaseClass.DBCon(); SqlCommand userCommand = new SqlCommand("select 图片 from tblwarpknitting where 题号 =" + id + "", userConnection); userConnection.Open(); SqlDataReader dr = userCommand.ExecuteReader(); if (dr.Read()) { if (dr["图片"] != DBNull.Value) { Response.Clear(); Response.ContentType = "image/BMP"; Response.BinaryWrite((byte[])dr["图片"]); Response.End(); } } dr.Close(); userConnection.Close(); }
2:使用js屏蔽刷新按钮等问题:
防止考生对考试的页面进行刷新,后退等操作,使用js屏蔽,但是在网上找到的解决方案都没有解决问题,按F5都还是能够刷新。
<script language="javascript" type="text/javascript"> <!-- self.moveTo(0,0); self.resizeTo(screen.availWidth,screen.availHeight); function document.onkeydown(){ event.keyCode = 0; event.returnvalue = false; } function keydown() { if(event.keyCode==8)//屏蔽退格键 { event.keyCode=0; event.returnValue=false; } if(event.keyCode==13)//屏蔽回车键 { event.keyCode=0; event.returnValue=false; } if(event.keyCode==116)//屏蔽F5刷新键 { event.keyCode=0; event.returnValue=false; } } function showtime() { var now=new Date(); years=now.getFullYear(); month=now.getMonth()+1; dates=now.getDate(); hours=now.getHours(); Minutes=now.getMinutes(); Seconds=now.getSeconds(); if(hours<10) hours="0"+hours; if(Minutes<10) Minutes="0"+Minutes; if(Seconds<10) Seconds="0"+Seconds; var titletext="当前日期时间为>>>"+years+"年"+month+"月"+dates+"日"+hours+":"+Minutes+":"+Seconds; setTimeout("showtime()",1000); document.title=titletext; } --> </script>
<body onkeydown="keydown()" onload="showtime()" oncontextmenu="return false" onselectstart="return false" background="../Image/back_01.gif" id="bntOk">