资源描述
徐州工业职业技术学院C#高级开发实训说明书
C#高级开发实训说明书
设计题目名称:在线考试系统
学 生 姓 名:
专业名称:
软件技术
班 级:
学 制:
三
学 号:
学历层次:
专 科
指导教师:
评 阅 人:
C#高级开发实训成绩评定书
专业、班级 姓名 日期
1、设计题目 在线考试系统
2、设计指导教师(签名)
3、设计评阅人(签名) 评阅日期
4、评定意见及成绩
年 月 日
目录
一.项目开发背景 4
二.项目功能需求分析 4
三.项目数据库设计 5
1、数据库概念设计: 5
2、数据库逻辑设计: 10
四.公共类设计 13
五.完成的主要功能 14
1.功能1:登录模块设计 14
2.功能2名称:抽取试题模块设计 15
3.功能3:试题类别管理模块设计 20
4功能4:试卷定制管理员模块设计 25
5功能5:用户试卷管理员模块设计 28
6功能6:用户信息管理员模块设计 33
六、致谢 37
一.项目开发背景
摘要:近年来,计算机技术的迅猛发展,给传统的办学提出了新的模式。绝大部分高等院校都已接入互联网并建成校园网,各校的硬件设施也已经比较完善,一现代计算机技术、网络技术为基础的数字化教学主要朝着信息化、网络化、现代化的目标迈进。开发无纸化在线考试系统,目的在于探索一种以互联网为基础的考试模式。通过这种新的模式提高了考试工作效率和标准化水平,使学校管理者、教师和学生在任何时候、任何地点都可以通过网络进行在线考试。
关键词:信息化、网络化、在线考试系统
二.项目功能需求分析
介绍系统计划设计的主要功能,简要描述功能的实现方案。
可以绘制功能框图。
在线考试系统前台功能结构图
登录模块
抽取试题模块
退出系统
选择考试科目
开始考试
修改密码
图1:在线考试系统前台功能结构图
在线考试系统后台管理
管理员登录
试题类别管理
试卷定制维护
用户试卷管理
用户信息管理
个人信息管理
后台管理模块
退出系统
图2:在线考试系统后台功能结构图
三.项目数据库设计
1、数据库概念设计:
开发在线考试系统时,为了灵活地维护系统,设计了后台管理员模块,通过后台管理员模块可以方便地堆整个在线考试系统进行维护。这时,必须建立一个数据表用于存储所有的管理员信息。管理员信息实体E-R图如图3所示。
管理员信息表
系统编号
登录名
登录密码
角色
图3:管理员信息实体E-R图
当考生成功登录在线考试系统后,可以根据需要选择考试的科目,考生不同可能选择的考试科目也会不同,系统必须提供一些参加考试的科目,供考生选择。这时,在数据库中应该建立一个存储所有参加考试科目的数据库表。开始科目信息实体E-R图如图4所示:
系统编号
考试科目名称
考试科目信息表
图4:考试科目信息实体E-R图
考生选择考试科目,开始在线考试。在规定时间内必须完成考试,否则系统会自动提交试卷,并且将考生的考试成绩保存在数据表中。这样,方便后期查询考生是否参加过考试,以及查询咯是考试得分。考试成绩信息实体E-R图如:5所示:
考试成绩信息表
系统编号
考生考号
考试科目名称
剩余考试时间
考试时间
考试得分
图5:考试成绩信息实体E-R图
在数据库中建立一个用于存储考生各项信息的数据表。其中包括考生登录时的账号(考生编号或考生学号)及密码。若某个考生参加了考试,系统会将考生答卷的最后得分保存到此数据库中,以便教师或考生对开始历史记录进行查询。考生信息实体E-R图如图6所示:
试卷类型信息表
系统编号
课程编号
试卷状态
试卷名称
图6:试卷类型信息实体E-R图
为了方便后台管理员对考试试题及考生考试结果进行管理,在数据库中必须建立一个数据表用于存储试卷信息。试卷详细信息实体E-R图如:7所示:
试卷详细信息表
系统编号
试卷编号
试卷类型
分数
试题编号
图7:试卷详细信息实体E-R图
在线考试系统中的考生答题答案是保存在数据库中的,所以必须在数据库中建立一个数据表用于存储考生所给的答案信息。考生答案信息实体E-R图如图8所示:
考生答案信息表
系统编号
考生编号
试卷编号
考试时间
考生答案
分数
试题类型
题目编号
图8:考生答案信息实体E-R图
在线考试系统中的考试单选题是通过对数据库中存储的所有试题产生的,所以必须在数据库中建立一个数据表用于存储单选试题信息,其中包括试题题目、试题的4个备选答案、正确答案以及所属的科目。单选题信息实体E-R图如图9所示:
单选题信息表
系统编号
课程编号
试题题目
试题正确答案
试题答案D
试题答案C
试题答案A
试题答案B
图9:试题信息实体E-R图
在线考试系统中的考试中的判断题是通过对数据库中存储的所有试题产生的,所以必须在数据库中建立一个数据表用于存储判断试题信息,其中包括试题题目、试题的正确答案和错误答案2个选项、正确答案以及所属的科目。判断题信息实体E-R图如图10所示:
判断题信息表
系统编号
课程编号
试题正确答案
试题题目
图10:判断题信息实体E-R图
在线考试系统中的考试中的多选题是通过对数据库中存储的试题产生的,所以必须在数据库中建立一个数据表用于存储多选试题信息,其中包括试题题目、试题的4个备选答案、正确答案以及所属的科目。多选题信息实体E-R图如图11所示:
多选题信息表
系统编号
课程编号
试题题目
试题正确答案
试题答案D
试题答案C
试题答案A
试题答案B
图11:多选题信息实体E-R图
在线考试系统中的考试中的简答题是通过对数据库中存储的试题产生的,所以必须在数据库中建立一个数据表用于存储简答试题信息,其中包括试题题目、试题的答案、及所属的科目。试题信息实体E-R图如图12所示:
问答题信息表
系统编号
课程编号
试题正确答案
试题题目
图12:问答题信息实体E-R图
2、数据库逻辑设计:
根据设计好的E_R图在数据库中创建各表,系统数据库中各表的结构如下。
表1:管理员用户表
字段名
数据类型
是否为空
约束
备注
UserID
varchar(50)
否
主键
编号
UserName
varchar(50)
是
管理员姓名
UserPwd
varchar(64)
是
管理员登录密码
RoleId
int
是
角色
表2:考试科目信息表
字段名
数据类型
是否允许
约束
备注
ID
int
否
主键
系统编号
Name
varchar(200)
是
考试科目名称
表3:考试成绩信息表
字段名
数据类型
是否为空
约束
备注
ID
Int
否
主键
系统编号
UserID
varchar(50)
是
参加考试的考生编号
PaperID
Int
是
考试科目编号
Score
Int
是
考生得分
ExamTime
datetime
是
参加考试的时间
JudgeTime
datetime
是
考试剩余时间
表4:试卷类型信息表
字段名
数据类型
是否为空
约束
备注
PaperID
Int
否
主键
系统编号
CourseID
Int
否
外键
课程编号
PaperName
Int
否
外键
试卷名称
PaperState
bit
否
外键
试卷类型
表5:试卷详细信息表
字段名
数据类型
是否为空
约束
备注
ID
Int
是
主键
系统编号
PaperID
varchar(200)
否
外键
试卷编号
Type
varchar(200)
否
外键
试题类型
TitleID
varchar(200)
否
外键
题目编号
Mark
varchar(200)
否
分数
表6:考生答案信息表
字段名
数据类型
是否为空
约束
备注
ID
Int
是
主键
系统编号
UserID
varchar(200)
否
外键
考生编号
PaperID
varchar(200)
否
外键
试卷编号
Type
varchar(200)
否
外键
试题类型
TitleID
varchar(200)
否
题目编号
Mark
varchar(200)
否
分数
UserAnswer
varchar(200)
否
考生答案
ExamTime
Int
否
考试时间
表7:单选题题信息表
字段名
数据类型
是否为空
约束
备注
ID
Int
否
主键
系统编号
CourseID
Int
否
外键
课程编号
Title
Varchar1000)
否
外键
题目
AnswerA
varchar(500)
否
外键
备选答案A
AnswerB
varchar(500)
否
备选答案B
AnswerC
varchar(500)
否
备选答案C
AnswerD
varchar(500)
否
备选答案D
Answer
varchar(2)
否
正确答案
表8 :判断题信息表
字段名
数据类型
是否为空
约束
备注
ID
Int
否
主键
系统编号
CourseID
Int
否
外键
课程编号
Title
Varchar1000)
否
外键
题目
Answer
bit
否
正确答案
表9 :多选题信息表
字段名
数据类型
是否为空
约束
备注
ID
Int
否
主键
系统编号
CourseID
Int
否
外键
课程编号
Title
Varchar1000)
否
外键
题目
AnswerA
varchar(500)
否
外键
备选答案A
AnswerB
varchar(500)
否
备选答案B
AnswerC
varchar(500)
否
备选答案C
AnswerD
varchar(500)
否
备选答案D
Answer
varchar(2)
否
正确答案
表10 :简答题信息表
字段名
数据类型
是否为空
约束
备注
ID
Int
否
主键
系统编号
CourseID
Int
否
外键
课程编号
Title
Varchar1000)
否
外键
题目
Answer
Varchar1000)
否
正确答案
表11 :填空题信息表
字段名
数据类型
是否为空
约束
备注
ID
Int
否
主键
系统编号
CourseID
Int
否
外键
课程编号
FrontTitle
varchar(500)
否
外键
题目
BackTitle
varchar(500)
否
题目
Answer
varchar(200)
正确答案
四.公共类设计
在开发项目中以类的形式来组织、封建一些常用的方法和事件,不仅可以提高代码的重用率,也大大方便了代码的管理。本系统中通过创建了三层架构OnLineExamBLL层、OnLineExamDAL层和一个公共类UserService设计,其中包含GetConnection ()方法、SelectAll()方法。具体代码如下:
public class UserService{
public List<Scores> SelectAll(string PaperID){
using (SqlConnection conn = DBHelp.GetConnection()){
string sql = @"select ID,Score.UserID,PaperID,Score,ExamTime,JudgeTime,Users.UserName from Score,Users
where Score.UserID=Users.UserID and PaperID='" + PaperID + "'";
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = sql;
conn.Open();
SqlDataReader dr = cmd.ExecuteReader();
List<Scores> list = new List<Scores>();
while (dr.Read()){
Users user = new Users();
Scores scores = new Scores();
scores.ID = Convert.ToInt32(dr["ID"]);
scores.UserID = dr["UserID"].ToString();
user.UserName = dr["UserName"].ToString();
scores.UserName = user.UserName;
scores.PaperID = Convert.ToInt32(dr["PaperID"]);
scores.Score = Convert.ToInt32(dr["Score"]);
scores.ExamTime = Convert.ToDateTime(dr["ExamTime"]);
scores.JudgeTime = Convert.ToDateTime(dr["JudgeTime"]);
list.Add(scores); }
dr.Close();
conn.Close();
return list;}}
public static SqlConnection GetConnection(){
string connStr = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
SqlConnection conn = new SqlConnection(connStr);
return conn;}
五.完成的主要功能
1.功能1:登录模块设计
(1)系统默认是不允许匿名登录的,只有使用管理员分配的账号和密码才能登录在线考试系统参加考试,这时就需要通过登录模块验证登录用户的合法性。登录模块是在线考试系统的第一道安全屏障,其运行结果如图所示:
图5-1 用户登录
(2) 实现过程:
新建一个网页,命名为Login.aspx,主要实现系统的登录功能。主要控件如表7所示:
表5-1:登录界面用到的主要控件
控件类型
控件ID
主要属性设置
用途
TextBox
txtUserID
无
输入登录用户名
txtPwd
TextModed属性设置为Password
输入登录用户密码
CheckBox
cbxRemeberUser
Checked属性设置为True
记住用户名
RequiredFieldValidator
RequiredFieldValidator1
Controltovalidate属性设置为txtUserID
进行验证
RequiredFieldValidator2
Controltovalidate属性设置为txtPwd
进行验证
Button
btlogin
Text属性设置为“登录”
登录
btconcel
Text属性设置为“取消”
取消
输入账号和密码等信息确认无误后,单机“登录“进行登录。程序首先会判断输入的用户名是否正确,如果正确则根据选择的用户名调用公共类中相应的方法验证账号和密码是否正确,如果正确,则会转向与登录身份符合的页面
(3)实现代码:
protected void Page_Load(object sender, EventArgs e) {
this.txtUserID.Focus();
if (!IsPostBack){
try{
HttpCookie readcookie = Request.Cookies["UsersID"];
this.txtUserID.Text = readcookie.Value; }
catch (Exception) {
this.txtUserID.Text = string.Empty; }
} }
protected void imgBtnLogin_Click(object sender, ImageClickEventArgs e){
string usersId = txtUserID.Text.Trim();
string pwdMd5 = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(txtPwd.Text.Trim(), "MD5").ToString();
Users u = new Users();
u.UserID = usersId;
u.UserPwd = pwdMd5;
bool success = UserManager.Login(ref u);
if (success){
if (u.UserPwd == pwdMd5)//输入密码与用户密码相同 {
if (this.cbxRemeberUser.Checked){
if (object.Equals(Request.Cookies["UsersID"], null)){
CreateCookie();}
else{
CreateCookie();}}
Session["userID"] = txtUserID.Text.Trim();//存储用户编号
Response.Redirect("Default.aspx");//转向管理员操作界面
}
else {
lblMessage.Text = "您输入的密码错误!";}}
else {
lblMessage.Text = "该用户不存在!";}}
private void CreateCookie(){
HttpCookie cookie = new HttpCookie("UsersID");
if (this.cbxRemeberUser.Checked){
cookie.Value = txtUserID.Text;}
cookie.Expires = DateTime.MaxValue;
Response.AppendCookie(cookie);}
2.功能2名称:抽取试题模块设计
(1)开发在线考试系统过程中,需要考虑如何将试题显示在页面上,即如何将试题从数据库中方读取出来。比较合理的做法是将所有试题信息存储在数据库中,然后随机抽取若干道试题,动态地显示在页面当中。为了实现此功能,设计出抽取试题模块,运行结果如图所示;
图5-2:随机抽取试题
(2)实现过程:
在随机抽取试题之前,考生要选择考试的科目,然后根据选择的科目随机从数据库中抽取试题,所以考生选择考试科目是随机抽取试题的条件,其运行结果如图所示:
图5-3:选择考试科目
新建一个网页,命名为UserTest.aspx,作为抽取试题页面及考试页面。该页面用到的主要控件如图所示:
表5-2:抽取试题页面用到的主要控件
控件类型
控件ID
主要属性设置
用途
Label
lblPaperName
无
显示考试科目
labUser
无
显示考生姓名
TextBox
timeBox
无
显示考试用时
Repeater
Repeater1
无
显示从数据库中抽取的试题
Button
btnsubmit
无
提交试卷
当页面加载时,根据考生选择的科目在数据库中随机抽取试题,并显示在Repeater控件中。
(3)实现代码如下:
protected int singeCount = 1;
protected void Page_Load(object sender, EventArgs e){
if (!Page.IsPostBack){
if (Session["userID"] == null){
Response.Redirect("Login.aspx");}
else{
string userId = Session["userID"].ToString();
string userName = UserManager.GetUserName(userId);
Label i1 = (Label)Page.FindControl("labUser");
i1.Text = userName;
lblPaperName.Text = Session["PaperName"].ToString();
GetParperAll();}}}
private void GetParperAll(){
IEnumerable list = sqlSingleMark.Select(DataSourceSelectArguments.Empty);
foreach (DataRowView o in list){
labSingle.Text = o[0].ToString();
break;}
IEnumerable list1 = SqlMultiMark.Select(DataSourceSelectArguments.Empty);
foreach (DataRowView o in list1){
Label3.Text = o[0].ToString();
break;}
IEnumerable list2 = SqlFillMark.Select(DataSourceSelectArguments.Empty);
foreach (DataRowView o in list2){
Label5.Text = o[0].ToString();
break;}
IEnumerable list3 = SqlJudgeMark.Select(DataSourceSelectArguments.Empty);
foreach (DataRowView o in list3){
Label4.Text = o[0].ToString();
break;}
IEnumerable list4 = SqlQuestionMark.Select(DataSourceSelectArguments.Empty);
foreach (DataRowView o in list4){
Label6.Text = o[0].ToString();
break;}}
protected void imgBtnSubmit_Click(object sender, ImageClickEventArgs e){
NewMethod();}
private void NewMethod(){
string Label = labSingle.Text;//单选分数
string paperid = Session["PaperID"].ToString();
string UserId = Session["userID"].ToString();
DBHelp db = new DBHelp();
foreach (RepeaterItem item in singleRep.Items){
HiddenField titleId = item.FindControl("titleId") as HiddenField;
string id = (string)titleId.Value;
string str = "";
if (((RadioButton)item.FindControl("rbA")).Checked) {
str = "A";}
else if (((RadioButton)item.FindControl("rbB")).Checked){
str = "B";}
else if (((RadioButton)item.FindControl("rbC")).Checked){
str = "C";}
else if (((RadioButton)item.FindControl("rbD")).Checked){
str = "D"; }
string single = "insert into UserAnswer(UserID,PaperID,Type,TitleID,Mark,UserAnswer,ExamTime) values('" + UserId + "','" + paperid + "','单选题','" + id + "','" + Label + "','" + str + "','" + DateTime.Now.ToString() + "')";
db.Insert(single);}
string labeM = Label3.Text;//多选分数
foreach (RepeaterItem item in Repeater2.Items){
HiddenField titleId = item.FindControl("titleId") as HiddenField;
string id = (string)titleId.Value;
string str = "";
if (((CheckBox)item.FindControl("CheckBox1")).Checked){
str += "A"; }
if (((CheckBox)item.FindControl("CheckBox2")).Checked){
str += "B";}
if (((CheckBox)item.FindControl("CheckBox3")).Checked){
str += "C";}
if (((CheckBox)item.FindControl("CheckBox4")).Checked){
str += "D";}
string Multi = "insert into UserAnswer(UserID,PaperID,Type,TitleID,Mark,UserAnswer,ExamTime) values('" + UserId + "','" + paperid + "','多选题','" + id + "','" + labeM + "','" + str + "','" + DateTime.Now.ToString() + "')";
db.Insert(Multi);}
string labeJ = Label4.Text;//判断分数
foreach (RepeaterItem item in Repeater3.Items){
HiddenField titleId = item.FindControl("titleId") as HiddenField;
string id = (string)titleId.Value;
string str = Convert.ToString(false);
if (((RadioButton)item.FindControl("rbA")).Checked){
str = Convert.ToString(true);}
else if (((RadioButton)item.FindControl("rbB")).Checked) {
str = Convert.ToString(false);}
string Judge = "insert into UserAnswer(UserID,PaperID,Type,TitleID,Mark,UserAnswer,ExamTime) values('" + UserId + "','" + paperid + "','判断题','" + id + "','" + labeJ + "','" + str + "','" + DateTime.Now.ToString() + "')";
db.Insert(Judge);}
string labeF = Label5.Text;//填空分数
foreach (RepeaterItem item in Repeater1.Items){
HiddenField titleId = item.FindControl("titleId") as HiddenField;
string id = (string)titleId.Value;
string str = "";
str = ((TextBox)item.FindControl("TextBox1")).Text.Trim();
string Fill = "insert into UserAnswer(UserID,PaperID,Type,TitleID,Mark,UserAnswer,ExamTime) values('" + UserId + "','" + paperid + "','填空题','" + id + "','" + labeF + "','" + str + "','" + DateTime.Now.ToString() + "')";
db.Insert(Fill); }
string labeQ = Label6.Text;//问答分数
foreach (RepeaterItem item in Repeater4.Items){
HiddenField titleId = item.FindControl("titleId") as HiddenField;
string id = (string)titleId.Value;
string str = "";
str = ((TextBox)item.FindControl("TextBox2")).Text.Trim();
string Que = "insert into UserAnswer(UserID,PaperID,Type,TitleID,Mark,UserAnswer,ExamTime) values('" + UserId
展开阅读全文