├── .gitignore ├── .vs └── config │ └── applicationhost.config ├── ExamSystem.sln ├── ExamSystem ├── App_Start │ └── RouteConfig.cs ├── Content │ ├── addexam.css │ ├── bootstrap.min.css │ └── common.css ├── Controllers │ ├── ExamController.cs │ ├── GroupController.cs │ ├── IndexController.cs │ ├── InstallController.cs │ ├── ManageController.cs │ ├── MessageController.cs │ ├── NewsController.cs │ ├── SearchController.cs │ └── UserController.cs ├── ExamSystem.csproj ├── Global.asax ├── Global.asax.cs ├── GlobalSuppressions.cs ├── Models │ ├── ChoiceQuestion.cs │ ├── DiscussQuestion.cs │ ├── Exam.cs │ ├── ExamSystemContext.cs │ ├── ExamsGroup.cs │ ├── FillQuestion.cs │ ├── ForgetPassword.cs │ ├── Group.cs │ ├── GroupMember.cs │ ├── Message.cs │ ├── News.cs │ ├── Question.cs │ ├── Result.cs │ ├── Section.cs │ ├── Subject.cs │ ├── User.cs │ └── UserInfo.cs ├── Mvc.sitemap ├── MvcSiteMapSchema.xsd ├── Properties │ ├── AssemblyInfo.cs │ └── PublishProfiles │ │ └── ExamSystem.pubxml ├── Scripts │ ├── MathJax.js │ ├── addexam.js │ ├── bootstrap.min.js │ ├── config │ │ └── TeX-MML-AM_CHTML.js │ ├── es.js │ ├── exam.js │ ├── fonts │ │ └── HTML-CSS │ │ │ └── Tex │ │ │ ├── otf │ │ │ ├── MathJax_Main-Regular.otf │ │ │ └── MathJax_Math-Italic.otf │ │ │ └── woff │ │ │ ├── MathJax_Main-Regular.woff │ │ │ └── MathJax_Math-Italic.woff │ ├── html5shiv.min.js │ ├── jax │ │ └── output │ │ │ └── CommonHTML │ │ │ ├── fonts │ │ │ └── Tex │ │ │ │ └── fontdata.js │ │ │ └── jax.js │ ├── jquery.min.js │ ├── register.js │ ├── respond.min.js │ └── review.js ├── Toolkit │ ├── Difficulty.cs │ ├── Encryption.cs │ ├── FileOperation.cs │ ├── Hash.cs │ ├── Pager.cs │ └── Permission.cs ├── ViewModels │ ├── ExamViewModel.cs │ ├── GroupViewModel.cs │ ├── MessageViewModel.cs │ ├── NewsViewModel.cs │ ├── ResultViewModel.cs │ ├── SectionViewModel.cs │ ├── SubjectViewModel.cs │ ├── UserInfoViewModel.cs │ └── UserViewModel.cs ├── Views │ ├── Exam │ │ ├── Attend.cshtml │ │ ├── Detail.cshtml │ │ ├── Index.cshtml │ │ ├── MyExams.cshtml │ │ ├── New.cshtml │ │ ├── Result.cshtml │ │ ├── Review.cshtml │ │ ├── ReviewList.cshtml │ │ ├── _detail_sidebar.cshtml │ │ └── _sidebar.cshtml │ ├── Group │ │ ├── AddMember.cshtml │ │ ├── Create.cshtml │ │ ├── Detail.cshtml │ │ ├── Exams.cshtml │ │ ├── Index.cshtml │ │ ├── Members.cshtml │ │ ├── _added_groups.cshtml │ │ └── _detail_sidebar.cshtml │ ├── Index │ │ ├── Index.cshtml │ │ ├── _exams.cshtml │ │ ├── _index_sidebar.cshtml │ │ └── _news.cshtml │ ├── Install │ │ └── Index.cshtml │ ├── Manage │ │ ├── AddQuestion.cshtml │ │ ├── AddSection.cshtml │ │ ├── AddSubject.cshtml │ │ ├── Index.cshtml │ │ ├── Questions.cshtml │ │ ├── Section.cshtml │ │ ├── Subject.cshtml │ │ └── _sidebar.cshtml │ ├── Message │ │ ├── Detail.cshtml │ │ ├── Index.cshtml │ │ ├── New.cshtml │ │ ├── SendBox.cshtml │ │ └── _sidebar.cshtml │ ├── News │ │ ├── Detail.cshtml │ │ ├── Edit.cshtml │ │ ├── Index.cshtml │ │ ├── New.cshtml │ │ ├── _detail_sidebar.cshtml │ │ ├── _list_sidebar.cshtml │ │ └── _manage_sidebar.cshtml │ ├── Search │ │ ├── Exams.cshtml │ │ ├── Groups.cshtml │ │ ├── News.cshtml │ │ ├── Users.cshtml │ │ └── _sidebar.cshtml │ ├── Shared │ │ ├── DisplayTemplates │ │ │ ├── CanonicalHelperModel.cshtml │ │ │ ├── MenuHelperModel.cshtml │ │ │ ├── MetaRobotsHelperModel.cshtml │ │ │ ├── SiteMapHelperModel.cshtml │ │ │ ├── SiteMapNodeModel.cshtml │ │ │ ├── SiteMapNodeModelList.cshtml │ │ │ ├── SiteMapPathHelperModel.cshtml │ │ │ └── SiteMapTitleHelperModel.cshtml │ │ ├── _layout.cshtml │ │ └── _signin.cshtml │ ├── User │ │ ├── Edit.cshtml │ │ ├── ForgetPassword.cshtml │ │ ├── Login.cshtml │ │ ├── Profile.cshtml │ │ ├── Recover.cshtml │ │ ├── Register.cshtml │ │ ├── Result.cshtml │ │ ├── Setting.cshtml │ │ ├── _not_login_sidebar.cshtml │ │ └── _sidebar.cshtml │ └── web.config ├── Web.Debug.config ├── Web.Release.config ├── Web.config ├── favicon.ico ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ └── glyphicons-halflings-regular.woff2 ├── install │ └── ExamSystem.sql └── packages.config ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Libraries 12 | *.lib 13 | *.a 14 | *.la 15 | *.lo 16 | 17 | # Shared objects (inc. Windows DLLs) 18 | *.dll 19 | *.so 20 | *.so.* 21 | *.dylib 22 | 23 | # Executables 24 | *.exe 25 | *.out 26 | *.app 27 | *.i*86 28 | *.x86_64 29 | *.hex 30 | *.bin 31 | 32 | # Debug files 33 | *.dSYM/ 34 | 35 | packages/ 36 | bin/ 37 | obj/ 38 | log/ 39 | result/ 40 | exams/ 41 | answer/ -------------------------------------------------------------------------------- /ExamSystem.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExamSystem", "ExamSystem\ExamSystem.csproj", "{90F46663-E2C3-4192-BDD2-690522236AEA}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {90F46663-E2C3-4192-BDD2-690522236AEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {90F46663-E2C3-4192-BDD2-690522236AEA}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {90F46663-E2C3-4192-BDD2-690522236AEA}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {90F46663-E2C3-4192-BDD2-690522236AEA}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /ExamSystem/App_Start/RouteConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Mvc; 2 | using System.Web.Routing; 3 | 4 | namespace ExamSystem 5 | { 6 | public class RouteConfig 7 | { 8 | public static void RegisterRoutes(RouteCollection routes) 9 | { 10 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 11 | 12 | routes.MapRoute( 13 | name: "Default", 14 | url: "{controller}/{action}/{id}", 15 | defaults: new { controller = "Index", action = "Index", id = UrlParameter.Optional } 16 | ); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ExamSystem/Content/addexam.css: -------------------------------------------------------------------------------- 1 | .add-question-content { 2 | display: none; 3 | } 4 | 5 | .exam-table-op { 6 | width: 90px; 7 | } 8 | 9 | .exam-table-score { 10 | width: 46px; 11 | } 12 | 13 | .exam-table-sc-answer { 14 | width: 46px; 15 | } 16 | 17 | .exam-table-sc-choice { 18 | width: 100px; 19 | text-overflow: ellipsis; 20 | max-width: 100px; 21 | overflow: hidden; 22 | } 23 | 24 | .exam-table-sc-text { 25 | width: 167px; 26 | text-overflow: ellipsis; 27 | max-width: 167px; 28 | overflow: hidden; 29 | } 30 | 31 | .exam-table-mc-answer { 32 | width: 55px; 33 | } 34 | 35 | .exam-table-mc-choice { 36 | width: 100px; 37 | text-overflow: ellipsis; 38 | max-width: 100px; 39 | overflow: hidden; 40 | } 41 | 42 | .exam-table-mc-text { 43 | width: 158px; 44 | text-overflow: ellipsis; 45 | max-width: 158px; 46 | overflow: hidden; 47 | } 48 | 49 | .exam-table-fd-answer { 50 | width: 200px; 51 | text-overflow: ellipsis; 52 | max-width: 200px; 53 | overflow: hidden; 54 | } 55 | 56 | .exam-table-fd-text { 57 | width: 413px; 58 | text-overflow: ellipsis; 59 | max-width: 413px; 60 | overflow: hidden; 61 | } 62 | 63 | .exam-table-qid, .exam-table-choice-number { 64 | display: none; 65 | } -------------------------------------------------------------------------------- /ExamSystem/Content/common.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | height: 100%; 3 | } 4 | 5 | .es-wrap { 6 | margin: 0; 7 | padding: 0; 8 | min-height: 100%; 9 | position: relative; 10 | } 11 | 12 | .es-top { 13 | background-color: #0767c8; 14 | border-bottom: 1px solid #002050; 15 | } 16 | 17 | .es-top-brand { 18 | margin-left: 150px; 19 | } 20 | 21 | .es-top-nav { 22 | margin-right: 150px; 23 | } 24 | 25 | .es-main-wrap { 26 | margin: 0 auto; 27 | width: 960px; 28 | overflow: hidden; 29 | padding-top: 81px; 30 | padding-bottom: 50px; 31 | display: block 32 | } 33 | 34 | .es-content { 35 | padding: 5px; 36 | float: left; 37 | width: 760px; 38 | } 39 | 40 | .es-sidebar { 41 | padding-top: 20px; 42 | padding-left: 20px; 43 | float: right; 44 | width: 200px; 45 | height: 100%; 46 | } 47 | 48 | .es-footer { 49 | width: 100%; 50 | height: 30px; 51 | line-height: 30px; 52 | bottom: 0; 53 | position: absolute; 54 | color: gray; 55 | text-align: center; 56 | display: block; 57 | overflow: hidden; 58 | } 59 | 60 | .es-signin { 61 | margin: 0 auto; 62 | width: 300px; 63 | background: #eee; 64 | border: 1px solid #eee; 65 | border-radius: 10px; 66 | } 67 | 68 | .es-profile .row { 69 | margin-top: 5px; 70 | } 71 | 72 | /* exam page */ 73 | .es-exam-body { 74 | background: #eee; 75 | } 76 | 77 | .es-paper { 78 | border: 1px solid #777; 79 | max-width: 960px; 80 | min-width: 600px; 81 | min-height: 100%; 82 | margin: 10px auto; 83 | background: white; 84 | } 85 | 86 | .es-exam-header { 87 | text-align: center; 88 | } 89 | 90 | .es-exam-content { 91 | font-size: 18px; 92 | margin: 50px 0; 93 | } 94 | 95 | .es-question { 96 | font-weight: normal; 97 | width: 100%; 98 | } 99 | 100 | .es-answer { 101 | margin-left: 25px !important; 102 | } 103 | 104 | .es-exam-submit { 105 | float: right; 106 | } 107 | 108 | .es-exam-list a { 109 | margin-right: 5px; 110 | } 111 | 112 | .es-pager-previous { 113 | display: inline-block; 114 | } 115 | 116 | .es-pager-num { 117 | display: inline-block; 118 | width: 626px; 119 | text-align: center; 120 | } 121 | 122 | .es-pager-next { 123 | display: inline-block; 124 | } 125 | 126 | .es-news-list .list-group-item-text { 127 | color: black; 128 | } 129 | 130 | .es-exam-list-enter { 131 | line-height: 1; 132 | } 133 | 134 | .es-list-more > a { 135 | margin: 0; 136 | } 137 | 138 | .es-warning { 139 | color: red; 140 | display: none; 141 | } 142 | 143 | .es-form .row { 144 | margin: 10px 0; 145 | } 146 | 147 | /* overload bootstrap */ 148 | .es-top a, .es-top a:hover, .es-top a:visited, .btn a, .btn a:hover, .btn a:visited { 149 | color: white; 150 | text-decoration: none; 151 | } 152 | 153 | .navbar-brand, .navbar-brand:hover, .dropdown-menu, .dropdown-menu>li>a, .navbar-nav>li>a, .nav .open>a { 154 | background-color: #0767c8; 155 | color: white; 156 | } 157 | 158 | .dropdown-menu>li>a:hover, .navbar-nav>li>a:hover, .navbar-nav>li>a:focus, .nav .open>a:hover, .nav .open>a:focus { 159 | background-color: #0060c1; 160 | color: #eee; 161 | } 162 | 163 | .nav-sidebar>li>a { 164 | font-size: 1.1em; 165 | color: #777; 166 | } 167 | 168 | .nav-sidebar>li>a:hover { 169 | background: #eeffff; 170 | color: #777; 171 | text-decoration: underline; 172 | } 173 | 174 | .badge { 175 | float: right; 176 | } 177 | 178 | .list-group-item-heading { 179 | color: #337ab7; 180 | } 181 | 182 | /* overload MathJax*/ 183 | .MJXc-display { 184 | display: inline-block; 185 | } -------------------------------------------------------------------------------- /ExamSystem/Controllers/IndexController.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Mvc; 2 | using log4net; 3 | 4 | namespace ExamSystem.Controllers 5 | { 6 | public class IndexController : Controller 7 | { 8 | private ILog log = LogManager.GetLogger(typeof(IndexController)); 9 | // GET: Index 10 | public ActionResult Index() 11 | { 12 | log.Info(Request.UserHostAddress + "访问主页。"); 13 | return View(); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /ExamSystem/Controllers/InstallController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Configuration; 3 | using System.Data.SqlClient; 4 | using System.IO; 5 | using System.Web.Configuration; 6 | using System.Web.Mvc; 7 | using ExamSystem.Toolkit; 8 | using log4net; 9 | 10 | namespace ExamSystem.Controllers 11 | { 12 | public class InstallController : Controller 13 | { 14 | ILog log = LogManager.GetLogger(typeof(InstallController)); 15 | // GET: Install 16 | public ActionResult Index() 17 | { 18 | log.Info(Request.UserHostAddress + "访问系统初始化页面。"); 19 | if (ConfigurationManager.ConnectionStrings["ExamSystemContext"].ConnectionString.Length != 0) 20 | { 21 | Response.Redirect("/Index"); 22 | } 23 | return View(); 24 | } 25 | 26 | public void Install() 27 | { 28 | log.Info(Request.UserHostAddress + "执行系统初始化。"); 29 | // concatenate connection string 30 | string connectionString = "data source = {server}; initial catalog = {dbname};integrated security = {type};" + 31 | "user id = {dbusername}; password = {dbpassword}; MultipleActiveResultSets = True; App = EntityFramework"; 32 | string[] keywords = { "server", "dbname", "type", "dbusername", "dbpassword" }; 33 | foreach (string key in keywords) 34 | { 35 | connectionString = connectionString.Replace("{" + key + "}", Request.Form[key]); 36 | } 37 | 38 | try 39 | { 40 | // get sql file path and create table into database. 41 | string path = HttpContext.Server.MapPath("/install/ExamSystem.sql"); 42 | FileInfo file = new FileInfo(path); 43 | string dbInstallString = file.OpenText().ReadToEnd(); 44 | 45 | using (SqlConnection connection = new SqlConnection(connectionString)) 46 | { 47 | SqlCommand command = new SqlCommand(dbInstallString, connection); 48 | command.Parameters.AddWithValue("@username", Request.Form["username"]); 49 | command.Parameters.AddWithValue("@password", Hash.SHA512(Request.Form["password"])); 50 | command.Parameters.AddWithValue("@nickname", Request.Form["nickname"]); 51 | command.Parameters.AddWithValue("@email", Request.Form["email"]); 52 | 53 | command.Connection.Open(); 54 | command.ExecuteNonQuery(); 55 | command.Connection.Close(); 56 | } 57 | } 58 | catch (Exception e) 59 | { 60 | log.Fatal(e.Message); 61 | Response.Redirect("/Install/Index?error=1"); 62 | return; 63 | } 64 | 65 | // write connection string into Web.config 66 | Configuration config = WebConfigurationManager.OpenWebConfiguration("~"); 67 | ConnectionStringsSection connectionSettings = (ConnectionStringsSection)config.GetSection("connectionStrings"); 68 | connectionSettings.ConnectionStrings["ExamSystemContext"].ConnectionString = connectionString; 69 | config.Save(); 70 | log.Info("已完成初始化,管理员" + Request.Form["username"]); 71 | 72 | Response.Redirect("/Index"); 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /ExamSystem/Controllers/MessageController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Web.Mvc; 4 | using ExamSystem.Models; 5 | using ExamSystem.Toolkit; 6 | using ExamSystem.ViewModels; 7 | using log4net; 8 | 9 | namespace ExamSystem.Controllers 10 | { 11 | public class MessageController : Controller 12 | { 13 | private ILog log = LogManager.GetLogger(typeof(NewsController)); 14 | private Pager pager = new Pager(); 15 | 16 | // GET: Message 17 | public ActionResult Index(int id = 1) 18 | { 19 | if (!Permission.LoginedNeed(Request, Response, Session)) 20 | { 21 | return null; 22 | } 23 | 24 | User user = (User)Session["user"]; 25 | IOrderedQueryable messages = MessageView.GetRecivedMessage(user.uid); 26 | ViewBag.messages = pager.GetPage(messages, id); 27 | ViewBag.page = id; 28 | ViewBag.pageNumber = pager.GetPageNumber(messages); 29 | 30 | return View(); 31 | } 32 | 33 | public ActionResult SendBox(int id = 1) 34 | { 35 | if (!Permission.LoginedNeed(Request, Response, Session)) 36 | { 37 | return null; 38 | } 39 | 40 | User user = (User)Session["user"]; 41 | IOrderedQueryable messages = MessageView.GetSendMessage(user.uid); 42 | ViewBag.messages = pager.GetPage(messages, id); 43 | ViewBag.page = id; 44 | ViewBag.pageNumber = pager.GetPageNumber(messages); 45 | 46 | return View(); 47 | } 48 | 49 | public ActionResult Detail(int id = 1) 50 | { 51 | if (!Permission.LoginedNeed(Request, Response, Session)) 52 | { 53 | return null; 54 | } 55 | 56 | User user = (User)Session["user"]; 57 | 58 | log.Info("uid:" + user.uid + "访问消息id:" + id); 59 | 60 | Message message = MessageView.GetMessage(id); 61 | if (user.uid != message.sender && user.uid != message.receiver) 62 | { 63 | Response.Redirect("/Message"); 64 | } 65 | 66 | bool isReceiver = false; 67 | if (user.uid == message.receiver) 68 | { 69 | if (message.read == false) 70 | { 71 | MessageView.ReadMessage(id); 72 | } 73 | isReceiver = true; 74 | } 75 | 76 | ViewBag.message = message; 77 | ViewBag.isReceiver = isReceiver; 78 | 79 | return View(); 80 | } 81 | 82 | public ActionResult New(int id = 0) 83 | { 84 | if (!Permission.LoginedNeed(Request, Response, Session)) 85 | { 86 | return null; 87 | } 88 | 89 | User receiver = UserView.GetUserById(id); 90 | 91 | ViewBag.receiver = receiver; 92 | 93 | return View(); 94 | } 95 | 96 | [HttpPost] 97 | public JsonResult Send() 98 | { 99 | 100 | string username = Request["username"]; 101 | User receiver = UserView.GetUserByUsername(username); 102 | if (!Permission.LoginedNeed(Request, Response, Session) || receiver == null) 103 | { 104 | return Json(false); 105 | } 106 | 107 | string title = Request["title"]; 108 | string content = Request["content"]; 109 | 110 | User sender = (User) Session["user"]; 111 | 112 | log.Info("uid:" + sender.uid + "发送消息至uid:" + receiver.uid); 113 | 114 | Message message = new Message 115 | { 116 | sender = sender.uid, 117 | receiver = receiver.uid, 118 | title = title, 119 | content = content, 120 | send_date = DateTime.Now, 121 | read = false 122 | }; 123 | 124 | return Json(MessageView.SendMessage(message)); 125 | } 126 | } 127 | } -------------------------------------------------------------------------------- /ExamSystem/Controllers/NewsController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Web.Mvc; 4 | using ExamSystem.Models; 5 | using ExamSystem.Toolkit; 6 | using ExamSystem.ViewModels; 7 | using log4net; 8 | 9 | namespace ExamSystem.Controllers 10 | { 11 | public class NewsController : Controller 12 | { 13 | private ILog log = LogManager.GetLogger(typeof(NewsController)); 14 | private static Pager pager = new Pager(); 15 | private static IOrderedQueryable newsCache = null; 16 | 17 | // GET: News 18 | public ActionResult Index(int id = 1) 19 | { 20 | IOrderedQueryable news = null; 21 | if (newsCache != null) 22 | { 23 | news = newsCache; 24 | } else 25 | { 26 | news = NewsView.GetAllNews(); 27 | newsCache = news; 28 | } 29 | 30 | int totalPageNumber = pager.GetPageNumber(news); 31 | if (id < 1 || id > totalPageNumber) 32 | { 33 | id = 1; 34 | } 35 | 36 | ViewBag.news = pager.GetPage(news, id); 37 | ViewBag.totalPageNumber = totalPageNumber; 38 | ViewBag.page = id; 39 | 40 | return View(); 41 | } 42 | 43 | public ActionResult Detail(int id = 1) 44 | { 45 | News news = NewsView.GetNewsById(id); 46 | if (news == null) 47 | { 48 | Response.Redirect("/Index"); 49 | return null; 50 | } 51 | 52 | ViewBag.news = news; 53 | return View(); 54 | } 55 | 56 | public ActionResult New() 57 | { 58 | log.Info(Request.UserHostAddress + "访问新闻发布页面"); 59 | if (!Permission.PremissionNeed(Request, Response, Session, UserRank.TEACHER)) 60 | { 61 | return null; 62 | } 63 | return View(); 64 | } 65 | 66 | public void Post() 67 | { 68 | if (!Permission.PremissionNeed(Request, Response, Session, UserRank.TEACHER)) 69 | { 70 | return ; 71 | } 72 | 73 | User user = (User) Session["user"]; 74 | string title = Request.Form["title"]; 75 | string content = Request.Form["content"]; 76 | 77 | if (title.Length != 0 && content.Length != 0) 78 | { 79 | log.Info("uid:" + user.uid + "发布新闻:" + title); 80 | News news = new News 81 | { 82 | publisher = user.uid, 83 | title = title, 84 | content = content, 85 | date = DateTime.Now 86 | }; 87 | NewsView.PostNewNews(news); 88 | } 89 | 90 | newsCache = NewsView.GetAllNews(); 91 | Response.Redirect("/News"); 92 | } 93 | 94 | public ActionResult Edit(int id = 1) 95 | { 96 | if (!Permission.PremissionNeed(Request, Response, Session, UserRank.ADMINISTATOR)) 97 | { 98 | return null; 99 | } 100 | 101 | log.Info(Request.UserHostAddress + "访问新闻编辑页面,nid:" + id); 102 | News news = NewsView.GetNewsById(id); 103 | if (news == null) 104 | { 105 | Response.Redirect("/Index"); 106 | return null; 107 | } 108 | ViewBag.news = news; 109 | 110 | return View(); 111 | } 112 | 113 | public void Save(int id) 114 | { 115 | if (!Permission.PremissionNeed(Request, Response, Session, UserRank.TEACHER)) 116 | { 117 | return ; 118 | } 119 | 120 | User user = (User)Session["user"]; 121 | string title = Request.Form["title"]; 122 | string content = Request.Form["content"]; 123 | 124 | if (title.Length != 0 && content.Length != 0) 125 | { 126 | log.Info("uid:" + user.uid + "编辑新闻id:" + id); 127 | NewsView.SaveNews(id, title, content); 128 | } 129 | 130 | Response.Redirect("/News"); 131 | } 132 | 133 | [HttpPost] 134 | public JsonResult Delete() 135 | { 136 | User user = (User) Session["user"]; 137 | int nid = Convert.ToInt32(Request["id"]); 138 | 139 | log.Info("uid:" + user.uid + "进行删除新闻操作,新闻id:" + nid); 140 | 141 | if (user.rank != (int) UserRank.ADMINISTATOR) 142 | { 143 | return Json(false); 144 | } 145 | 146 | bool result = NewsView.DeleteNews(nid); 147 | newsCache = NewsView.GetAllNews(); 148 | 149 | return Json(result); 150 | } 151 | } 152 | } -------------------------------------------------------------------------------- /ExamSystem/Controllers/SearchController.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Web.Mvc; 3 | using ExamSystem.Models; 4 | using ExamSystem.Toolkit; 5 | using ExamSystem.ViewModels; 6 | using log4net; 7 | 8 | namespace ExamSystem.Controllers 9 | { 10 | public class SearchController : Controller 11 | { 12 | private ILog log = LogManager.GetLogger(typeof(NewsController)); 13 | 14 | // GET: Search 15 | public void Index() 16 | { 17 | string type = Request.QueryString["type"]; 18 | string content = Request.QueryString["content"]; 19 | string url = ""; 20 | 21 | switch (type) 22 | { 23 | case "2": 24 | url = "/Search/Exams"; 25 | break; 26 | case "3": 27 | url = "/Search/Groups"; 28 | break; 29 | case "4": 30 | url = "/Search/Users"; 31 | break; 32 | case "1": 33 | default: 34 | url = "/Search/News"; 35 | break; 36 | } 37 | 38 | url += "?content=" + content; 39 | Response.Redirect(url); 40 | } 41 | 42 | public ActionResult News(int id = 1) 43 | { 44 | Pager pager = new Pager(); 45 | 46 | string keyword = Request.QueryString["content"]; 47 | IOrderedQueryable news = NewsView.GetNewsByKeyword(keyword); 48 | ViewBag.page = id; 49 | ViewBag.news = pager.GetPage(news, id); 50 | ViewBag.pageNumber = pager.GetPageNumber(news); 51 | ViewBag.keyword = keyword; 52 | 53 | return View(); 54 | } 55 | 56 | public ActionResult Exams(int id = 1) 57 | { 58 | Pager pager = new Pager(); 59 | 60 | string keyword = Request.QueryString["content"]; 61 | IOrderedQueryable exams = ExamView.GetExamsByKeyword(keyword); 62 | ViewBag.page = id; 63 | ViewBag.exams = pager.GetPage(exams, id); 64 | ViewBag.pageNumber = pager.GetPageNumber(exams); 65 | ViewBag.keyword = keyword; 66 | 67 | return View(); 68 | } 69 | 70 | public ActionResult Groups(int id = 1) 71 | { 72 | Pager pager = new Pager(); 73 | 74 | string keyword = Request.QueryString["content"]; 75 | IOrderedQueryable groups = GroupView.GetGroupByKeywork(keyword); 76 | ViewBag.page = id; 77 | ViewBag.groups = pager.GetPage(groups, id); 78 | ViewBag.pageNumber = pager.GetPageNumber(groups); 79 | ViewBag.keyword = keyword; 80 | 81 | return View(); 82 | } 83 | 84 | public ActionResult Users(int id = 1) 85 | { 86 | Pager pager = new Pager(); 87 | 88 | string keyword = Request.QueryString["content"]; 89 | IOrderedQueryable users = UserView.GetUserByKeyword(keyword); 90 | ViewBag.page = id; 91 | ViewBag.users = pager.GetPage(users, id); 92 | ViewBag.pageNumber = pager.GetPageNumber(users); 93 | ViewBag.keyword = keyword; 94 | 95 | return View(); 96 | } 97 | } 98 | } -------------------------------------------------------------------------------- /ExamSystem/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="ExamSystem.MvcApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /ExamSystem/Global.asax.cs: -------------------------------------------------------------------------------- 1 | using ExamSystem.Toolkit; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Web; 6 | using System.Web.Mvc; 7 | using System.Web.Routing; 8 | 9 | namespace ExamSystem 10 | { 11 | public class MvcApplication : System.Web.HttpApplication 12 | { 13 | protected void Application_Start() 14 | { 15 | AreaRegistration.RegisterAllAreas(); 16 | RouteConfig.RegisterRoutes(RouteTable.Routes); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ExamSystem/GlobalSuppressions.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghosind/ExamSystem/ee8103a8ce26b30b9fea97258fb3c227200703d2/ExamSystem/GlobalSuppressions.cs -------------------------------------------------------------------------------- /ExamSystem/Models/ChoiceQuestion.cs: -------------------------------------------------------------------------------- 1 | namespace ExamSystem.Models 2 | { 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | 6 | public partial class ChoiceQuestion 7 | { 8 | public int? qid { get; set; } 9 | 10 | [Column(TypeName = "text")] 11 | public string content { get; set; } 12 | 13 | [Key] 14 | [Column(Order = 0)] 15 | public int choice_num { get; set; } 16 | 17 | [Key] 18 | [Column(Order = 1, TypeName = "text")] 19 | public string choice_1 { get; set; } 20 | 21 | [Key] 22 | [Column(Order = 2, TypeName = "text")] 23 | public string choice_2 { get; set; } 24 | 25 | [Column(TypeName = "text")] 26 | public string choice_3 { get; set; } 27 | 28 | [Column(TypeName = "text")] 29 | public string choice_4 { get; set; } 30 | 31 | [Key] 32 | [Column(Order = 3)] 33 | [DatabaseGenerated(DatabaseGeneratedOption.None)] 34 | public int answer { get; set; } 35 | 36 | public virtual Question Question { get; set; } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ExamSystem/Models/DiscussQuestion.cs: -------------------------------------------------------------------------------- 1 | namespace ExamSystem.Models 2 | { 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | 6 | public partial class DiscussQuestion 7 | { 8 | public int? qid { get; set; } 9 | 10 | [Key] 11 | [Column(Order = 0, TypeName = "text")] 12 | public string content { get; set; } 13 | 14 | [Key] 15 | [Column(Order = 1, TypeName = "text")] 16 | public string answer { get; set; } 17 | 18 | public virtual Question Question { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /ExamSystem/Models/Exam.cs: -------------------------------------------------------------------------------- 1 | namespace ExamSystem.Models 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel.DataAnnotations; 6 | using System.ComponentModel.DataAnnotations.Schema; 7 | 8 | public partial class Exam 9 | { 10 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] 11 | public Exam() 12 | { 13 | ExamsGroups = new HashSet(); 14 | Results = new HashSet(); 15 | } 16 | 17 | [Key] 18 | public int eid { get; set; } 19 | 20 | [Required] 21 | [StringLength(128)] 22 | public string title { get; set; } 23 | 24 | public int? subject { get; set; } 25 | 26 | public int time { get; set; } 27 | 28 | public DateTime start_date { get; set; } 29 | 30 | public DateTime end_date { get; set; } 31 | 32 | [Required] 33 | [StringLength(128)] 34 | public string exam_path { get; set; } 35 | 36 | [Required] 37 | [StringLength(128)] 38 | public string answer_path { get; set; } 39 | 40 | public bool must_take { get; set; } 41 | 42 | [Column("public")] 43 | public bool _public { get; set; } 44 | 45 | public virtual Subject Subject1 { get; set; } 46 | 47 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 48 | public virtual ICollection ExamsGroups { get; set; } 49 | 50 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 51 | public virtual ICollection Results { get; set; } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ExamSystem/Models/ExamsGroup.cs: -------------------------------------------------------------------------------- 1 | namespace ExamSystem.Models 2 | { 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | 6 | [Table("ExamsGroup")] 7 | public partial class ExamsGroup 8 | { 9 | public int? eid { get; set; } 10 | 11 | [Key] 12 | [DatabaseGenerated(DatabaseGeneratedOption.None)] 13 | public int gid { get; set; } 14 | 15 | public virtual Exam Exam { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ExamSystem/Models/FillQuestion.cs: -------------------------------------------------------------------------------- 1 | namespace ExamSystem.Models 2 | { 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | 6 | public partial class FillQuestion 7 | { 8 | public int? qid { get; set; } 9 | 10 | [Key] 11 | [Column(Order = 0, TypeName = "text")] 12 | public string content { get; set; } 13 | 14 | [Key] 15 | [Column(Order = 1, TypeName = "text")] 16 | public string answer { get; set; } 17 | 18 | public virtual Question Question { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /ExamSystem/Models/ForgetPassword.cs: -------------------------------------------------------------------------------- 1 | namespace ExamSystem.Models 2 | { 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | 6 | [Table("ForgetPassword")] 7 | public partial class ForgetPassword 8 | { 9 | public int? uid { get; set; } 10 | 11 | [Key] 12 | public string code { get; set; } 13 | 14 | public virtual User User { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ExamSystem/Models/Group.cs: -------------------------------------------------------------------------------- 1 | namespace ExamSystem.Models 2 | { 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.ComponentModel.DataAnnotations.Schema; 6 | 7 | [Table("Group")] 8 | public partial class Group 9 | { 10 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] 11 | public Group() 12 | { 13 | GroupMembers = new HashSet(); 14 | } 15 | 16 | [Key] 17 | public int gid { get; set; } 18 | 19 | [Required] 20 | [StringLength(64)] 21 | public string group_name { get; set; } 22 | 23 | public int? owner_uid { get; set; } 24 | 25 | public int number { get; set; } 26 | 27 | public bool allow_join { get; set; } 28 | 29 | public bool allow_quit { get; set; } 30 | 31 | public virtual User User { get; set; } 32 | 33 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 34 | public virtual ICollection GroupMembers { get; set; } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ExamSystem/Models/GroupMember.cs: -------------------------------------------------------------------------------- 1 | namespace ExamSystem.Models 2 | { 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | 6 | [Table("GroupMember")] 7 | public partial class GroupMember 8 | { 9 | [Key] 10 | [Column(Order = 1)] 11 | public int? gid { get; set; } 12 | 13 | [Key] 14 | [Column(Order = 2)] 15 | public int? uid { get; set; } 16 | 17 | [DatabaseGenerated(DatabaseGeneratedOption.None)] 18 | public int rank { get; set; } 19 | 20 | public virtual Group Group { get; set; } 21 | 22 | public virtual User User { get; set; } 23 | } 24 | 25 | public enum MemberRank 26 | { 27 | MEMBER = 0, 28 | ADMINISTRATOR = 1, 29 | CREATOR = 2 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ExamSystem/Models/Message.cs: -------------------------------------------------------------------------------- 1 | namespace ExamSystem.Models 2 | { 3 | using System; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.ComponentModel.DataAnnotations.Schema; 6 | 7 | [Table("Message")] 8 | public partial class Message 9 | { 10 | [Key] 11 | public int mid { get; set; } 12 | 13 | public int? sender { get; set; } 14 | 15 | public int? receiver { get; set; } 16 | 17 | [Required] 18 | [StringLength(128)] 19 | public string title { get; set; } 20 | 21 | [Column(TypeName = "text")] 22 | [Required] 23 | public string content { get; set; } 24 | 25 | public DateTime send_date { get; set; } 26 | 27 | public bool read { get; set; } 28 | 29 | public virtual User User { get; set; } 30 | 31 | public virtual User User1 { get; set; } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ExamSystem/Models/News.cs: -------------------------------------------------------------------------------- 1 | namespace ExamSystem.Models 2 | { 3 | using System; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.ComponentModel.DataAnnotations.Schema; 6 | 7 | public partial class News 8 | { 9 | [Key] 10 | public int nid { get; set; } 11 | 12 | public int? publisher { get; set; } 13 | 14 | [Required] 15 | [StringLength(256)] 16 | public string title { get; set; } 17 | 18 | [Column(TypeName = "text")] 19 | [Required] 20 | public string content { get; set; } 21 | 22 | public DateTime date { get; set; } 23 | 24 | public virtual User User { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ExamSystem/Models/Question.cs: -------------------------------------------------------------------------------- 1 | namespace ExamSystem.Models 2 | { 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | 6 | public partial class Question 7 | { 8 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] 9 | public Question() 10 | { 11 | ChoiceQuestions = new HashSet(); 12 | DiscussQuestions = new HashSet(); 13 | FillQuestions = new HashSet(); 14 | } 15 | 16 | [Key] 17 | public int qid { get; set; } 18 | 19 | public int type { get; set; } 20 | 21 | public int? kid { get; set; } 22 | 23 | public double suggest_difficulty { get; set; } 24 | 25 | public double difficulty { get; set; } 26 | 27 | public int number { get; set; } 28 | 29 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 30 | public virtual ICollection ChoiceQuestions { get; set; } 31 | 32 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 33 | public virtual ICollection DiscussQuestions { get; set; } 34 | 35 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 36 | public virtual ICollection FillQuestions { get; set; } 37 | 38 | public virtual Section Section { get; set; } 39 | } 40 | 41 | public enum QuestionType 42 | { 43 | SINGLECHOICE = 0, 44 | MULTICHOICE = 1, 45 | FILLIN = 2, 46 | DISCUSS = 3 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ExamSystem/Models/Result.cs: -------------------------------------------------------------------------------- 1 | namespace ExamSystem.Models 2 | { 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | 6 | [Table("Result")] 7 | public partial class Result 8 | { 9 | public int? uid { get; set; } 10 | 11 | [Key] 12 | [Column(Order = 1)] 13 | public int? eid { get; set; } 14 | 15 | [Key] 16 | [Column(Order = 0)] 17 | public string answer { get; set; } 18 | 19 | public int? reviewer { get; set; } 20 | 21 | public int score { get; set; } 22 | 23 | public virtual Exam Exam { get; set; } 24 | 25 | public virtual User User { get; set; } 26 | 27 | public virtual User User1 { get; set; } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ExamSystem/Models/Section.cs: -------------------------------------------------------------------------------- 1 | namespace ExamSystem.Models 2 | { 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.ComponentModel.DataAnnotations.Schema; 6 | 7 | [Table("Section")] 8 | public partial class Section 9 | { 10 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] 11 | public Section() 12 | { 13 | Questions = new HashSet(); 14 | } 15 | 16 | [Key] 17 | public int kid { get; set; } 18 | 19 | [Required] 20 | [StringLength(256)] 21 | public string section_name { get; set; } 22 | 23 | public int? sid { get; set; } 24 | 25 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 26 | public virtual ICollection Questions { get; set; } 27 | 28 | public virtual Subject Subject { get; set; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ExamSystem/Models/Subject.cs: -------------------------------------------------------------------------------- 1 | namespace ExamSystem.Models 2 | { 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.ComponentModel.DataAnnotations.Schema; 6 | 7 | [Table("Subject")] 8 | public partial class Subject 9 | { 10 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] 11 | public Subject() 12 | { 13 | Exams = new HashSet(); 14 | Sections = new HashSet
(); 15 | } 16 | 17 | [Key] 18 | public int sid { get; set; } 19 | 20 | [Required] 21 | [StringLength(128)] 22 | public string subject_name { get; set; } 23 | 24 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 25 | public virtual ICollection Exams { get; set; } 26 | 27 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 28 | public virtual ICollection
Sections { get; set; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ExamSystem/Models/User.cs: -------------------------------------------------------------------------------- 1 | namespace ExamSystem.Models 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel.DataAnnotations; 6 | using System.ComponentModel.DataAnnotations.Schema; 7 | 8 | [Table("User")] 9 | public partial class User 10 | { 11 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] 12 | public User() 13 | { 14 | Groups = new HashSet(); 15 | Messages = new HashSet(); 16 | Messages1 = new HashSet(); 17 | News = new HashSet(); 18 | ForgetPasswords = new HashSet(); 19 | GroupMembers = new HashSet(); 20 | Results = new HashSet(); 21 | Results1 = new HashSet(); 22 | UserInfoes = new HashSet(); 23 | } 24 | 25 | [Key] 26 | public int uid { get; set; } 27 | 28 | [Required] 29 | [StringLength(64)] 30 | public string username { get; set; } 31 | 32 | [Required] 33 | [StringLength(128)] 34 | public string password { get; set; } 35 | 36 | [Required] 37 | [StringLength(32)] 38 | public string name { get; set; } 39 | 40 | public int rank { get; set; } 41 | 42 | public DateTime login_date { get; set; } 43 | 44 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 45 | public virtual ICollection Groups { get; set; } 46 | 47 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 48 | public virtual ICollection Messages { get; set; } 49 | 50 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 51 | public virtual ICollection Messages1 { get; set; } 52 | 53 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 54 | public virtual ICollection News { get; set; } 55 | 56 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 57 | public virtual ICollection ForgetPasswords { get; set; } 58 | 59 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 60 | public virtual ICollection GroupMembers { get; set; } 61 | 62 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 63 | public virtual ICollection Results { get; set; } 64 | 65 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 66 | public virtual ICollection Results1 { get; set; } 67 | 68 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 69 | public virtual ICollection UserInfoes { get; set; } 70 | } 71 | 72 | public enum UserRank 73 | { 74 | BLOCKED = 0, 75 | STUDENT = 1, 76 | TEACHER = 2, 77 | ADMINISTATOR = 3 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /ExamSystem/Models/UserInfo.cs: -------------------------------------------------------------------------------- 1 | namespace ExamSystem.Models 2 | { 3 | using System; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.ComponentModel.DataAnnotations.Schema; 6 | 7 | [Table("UserInfo")] 8 | public partial class UserInfo 9 | { 10 | public int? uid { get; set; } 11 | 12 | [Key] 13 | [Column(Order = 0)] 14 | [StringLength(2)] 15 | public string sex { get; set; } 16 | 17 | [Key] 18 | [Column(Order = 1)] 19 | public DateTime birthday { get; set; } 20 | 21 | [StringLength(11)] 22 | public string telephone { get; set; } 23 | 24 | [Key] 25 | [Column(Order = 2)] 26 | public string email { get; set; } 27 | 28 | [Key] 29 | [Column(Order = 3)] 30 | public bool email_valid { get; set; } 31 | 32 | [StringLength(128)] 33 | public string address { get; set; } 34 | 35 | [StringLength(256)] 36 | public string description { get; set; } 37 | 38 | [Key] 39 | [Column(Order = 4)] 40 | public DateTime reg_date { get; set; } 41 | 42 | public virtual User User { get; set; } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /ExamSystem/Mvc.sitemap: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /ExamSystem/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("ExamSystem")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("ExamSystem")] 12 | [assembly: AssemblyCopyright("Copyright © 2017")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("90f46663-e2c3-4192-bdd2-690522236aea")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Revision and Build Numbers 32 | // by using the '*' as shown below: 33 | [assembly: AssemblyVersion("1.0.0.0")] 34 | [assembly: AssemblyFileVersion("1.0.0.0")] 35 | 36 | [assembly: log4net.Config.XmlConfigurator(ConfigFile = "Web.config", Watch = true)] -------------------------------------------------------------------------------- /ExamSystem/Properties/PublishProfiles/ExamSystem.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | FileSystem 9 | Release 10 | Any CPU 11 | 12 | True 13 | False 14 | C:\Users\wind\Desktop\Online Examination System\publish 15 | False 16 | 17 | -------------------------------------------------------------------------------- /ExamSystem/Scripts/es.js: -------------------------------------------------------------------------------- 1 | function logout() { 2 | $.ajax({ 3 | type: "POST", 4 | url: "/User/Logout", 5 | success: function (data) { 6 | location.href = location.pathname; 7 | } 8 | }); 9 | } 10 | 11 | function text_validate(text) { 12 | text = text.replace(//g, ">"); 14 | return text; 15 | } 16 | 17 | function join_group(id) { 18 | $.ajax({ 19 | type: "POST", 20 | url: "/Group/Join", 21 | data: "gid=" + id, 22 | success: function (data) { 23 | if (data === true) { 24 | alert("加入成功"); 25 | location.href = "/Group/Detail/" + id; 26 | } else { 27 | alert("加入失败"); 28 | } 29 | } 30 | }); 31 | } 32 | 33 | function dismiss_group(id) { 34 | if (confirm("确定解散群组?")) { 35 | $.ajax({ 36 | type: "POST", 37 | url: "/Group/Dismiss", 38 | data: "gid=" + id, 39 | success: function (data) { 40 | if (data === true) { 41 | alert("群组已解散"); 42 | location.href = "/Group/Index"; 43 | } else { 44 | alert("解散失败"); 45 | } 46 | } 47 | }); 48 | } 49 | } 50 | 51 | function quit_group(id) { 52 | if (confirm("确定退出群组?")) { 53 | $.ajax({ 54 | type: "POST", 55 | url: "/Group/Quit", 56 | data: "gid=" + id, 57 | success: function (data) { 58 | if (data === true) { 59 | alert("已退出群组"); 60 | location.href = "/Group/Index"; 61 | } else { 62 | alert("退出失败"); 63 | } 64 | } 65 | }); 66 | } 67 | } -------------------------------------------------------------------------------- /ExamSystem/Scripts/exam.js: -------------------------------------------------------------------------------- 1 | function load_questions(content) { 2 | content = content.replace(/</g, '<').replace(/>/g, '>'); 3 | var parser = new DOMParser(); 4 | var xml = parser.parseFromString(content, "text/xml"); 5 | var scnum = new Number($(xml).find("totalsc").find("number").text()); 6 | var mcnum = new Number($(xml).find("totalmc").find("number").text()); 7 | var fqnum = new Number($(xml).find("totalfq").find("number").text()); 8 | var dqnum = new Number($(xml).find("totaldq").find("number").text()); 9 | var number = 0; 10 | 11 | if (scnum != 0) { 12 | $(".es-exam-content").append("

单项选择题(共" + scnum + "题," + 13 | $(xml).find("totalsc").find("score").text() + "分。下列每题给出的选项中,只有一个是符合题目要求的)

"); 14 | 15 | $(xml).find("singlechoice").each(function () { 16 | number++; 17 | $(".es-exam-content").append("
"); 19 | var choice_number = new Number($(this).find("choicenumber").text()); 20 | for (var i = 0; i < choice_number; i++) { 21 | $(".es-exam-content").append("" + 23 | $(this).find("choice" + String.fromCharCode(97 + i)).text() + "
"); 24 | } 25 | $(".es-exam-content").append("
"); 26 | }); 27 | } 28 | 29 | if (mcnum != 0) { 30 | $(".es-exam-content").append("

多项选择题(共" + mcnum + "题," + 31 | $(xml).find("totalmc").find("score").text() + 32 | "分。下列每题给出的选项中,有一个或一个以上是符合题目要求的,多选漏选均不得分)

"); 33 | 34 | $(xml).find("multichoice").each(function () { 35 | number++; 36 | $(".es-exam-content").append("
"); 38 | var choice_number = new Number($(this).find("choicenumber").text()); 39 | for (var i = 0; i < choice_number; i++) { 40 | $(".es-exam-content").append("" + 42 | $(this).find("choice" + String.fromCharCode(97 + i)).text() + "
"); 43 | } 44 | $(".es-exam-content").append("
"); 45 | }); 46 | } 47 | 48 | if (fqnum != 0) { 49 | $(".es-exam-content").append("

填空题(共" + fqnum + "题," + 50 | $(xml).find("totalfq").find("score").text() + 51 | "分。)

"); 52 | 53 | $(xml).find("fillin").each(function () { 54 | number++; 55 | $(".es-exam-content").append("
"); 57 | $(".es-exam-content").append("
"); 59 | }); 60 | } 61 | 62 | if (dqnum != 0) { 63 | $(".es-exam-content").append("

问答题(共" + dqnum + "题," + 64 | $(xml).find("totaldq").find("score").text() + 65 | "分。)

"); 66 | 67 | $(xml).find("discuss").each(function () { 68 | number++; 69 | $(".es-exam-content").append("
"); 71 | $(".es-exam-content").append(" 44 | 45 | 46 |
47 |
48 | 49 |
50 |
51 | 52 | 67 | -------------------------------------------------------------------------------- /ExamSystem/Views/Message/SendBox.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "发件箱"; 3 | List messages = ViewBag.messages; 4 | int page = ViewBag.page; 5 | int totalPageNumber = ViewBag.pageNumber; 6 | Layout = "~/Views/Shared/_layout.cshtml"; 7 | } 8 | @section sidebar { 9 | @Html.Partial("_sidebar") 10 | } 11 | 36 |
37 |
38 | @if (page > 1) 39 | { 40 | 上一页 41 | } 42 | else 43 | { 44 | 上一页 45 | } 46 |
第 @page 页
47 | @if (page < totalPageNumber) 48 | { 49 | 下一页 50 | } 51 | else 52 | { 53 | 下一页 54 | } 55 |
-------------------------------------------------------------------------------- /ExamSystem/Views/Message/_sidebar.cshtml: -------------------------------------------------------------------------------- 1 | 
  • 返回
  • 2 |
  • 发消息
  • 3 |
  • 收件箱
  • 4 |
  • 发件箱
  • 5 |
    -------------------------------------------------------------------------------- /ExamSystem/Views/News/Detail.cshtml: -------------------------------------------------------------------------------- 1 |  2 | @{ 3 | News news = ViewBag.news; 4 | ViewBag.Title = news.title; 5 | Layout = "~/Views/Shared/_layout.cshtml"; 6 | } 7 | @section sidebar { 8 | @Html.Partial("_detail_sidebar") 9 | } 10 |
    11 |

    @news.title

    12 |
    13 |
    发布人:
    14 |
    @UserView.GetUserById((int) news.publisher).name
    15 |
    发布时间:
    16 |
    @news.date
    17 |
    18 |
    19 | @news.content 20 |
    21 | @{ 22 | User user = (User)Session["user"]; 23 | if (user != null && user.rank == (int) UserRank.ADMINISTATOR) 24 | { 25 | 40 | 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /ExamSystem/Views/News/Edit.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.title = "新闻编辑"; 3 | Layout = "~/Views/Shared/_layout.cshtml"; 4 | News news = ViewBag.news; 5 | } 6 | @section sidebar { 7 | @Html.Partial("_manage_sidebar") 8 | } 9 |
    10 |
    11 |
    12 | 13 |
    14 |
    15 | 16 |
    17 |
    18 |
    19 |
    20 | 21 |
    22 |
    23 | 24 |
    25 |
    26 |
    27 |
    28 | 29 | 30 |
    31 |
    32 |
    -------------------------------------------------------------------------------- /ExamSystem/Views/News/Index.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "新闻列表"; 3 | Layout = "~/Views/Shared/_layout.cshtml"; 4 | List news = ViewBag.news; 5 | int page = ViewBag.page; 6 | int totalPageNumber = ViewBag.totalPageNumber; 7 | } 8 | @section sidebar { 9 | @Html.Partial("_list_sidebar") 10 | } 11 |
      12 | @foreach (var n in news) 13 | { 14 |
    • 15 |
      16 | @n.title 17 |
      18 |
      19 | @n.content.Substring(0, (n.content.Length < 50 ? n.content.Length : 50)) 20 |
      21 |
    • 22 | } 23 |
    24 |
    25 |
    26 | @if (page > 1) 27 | { 28 | 上一页 29 | } 30 | else 31 | { 32 | 上一页 33 | } 34 |
    第 @page 页
    35 | @if (page < totalPageNumber) 36 | { 37 | 下一页 38 | } 39 | else 40 | { 41 | 下一页 42 | } 43 |
    -------------------------------------------------------------------------------- /ExamSystem/Views/News/New.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "发布新闻"; 3 | Layout = "~/Views/Shared/_layout.cshtml"; 4 | } 5 | @section sidebar { 6 | @Html.Partial("_manage_sidebar") 7 | } 8 |
    9 |
    10 |
    11 | 12 |
    13 |
    14 | 15 |
    16 |
    17 |
    18 |
    19 | 20 |
    21 |
    22 | 23 |
    24 |
    25 |
    26 |
    27 | 28 | 29 |
    30 |
    31 |
    32 | -------------------------------------------------------------------------------- /ExamSystem/Views/News/_detail_sidebar.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | User user = (User)Session["user"]; 3 | if (user != null && user.rank == (int)UserRank.ADMINISTATOR) 4 | { 5 |
  • 编辑
  • 6 |
  • 删除
  • 7 |
    8 | } 9 | } 10 |
  • 返回
  • 11 |
  • 新闻
  • 12 |
  • 考试
  • 13 |
    -------------------------------------------------------------------------------- /ExamSystem/Views/News/_list_sidebar.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | User user = (User)Session["user"]; 3 | if (user != null && user.rank >= (int)UserRank.TEACHER) 4 | { 5 |
  • 发布新闻
  • 6 |
    7 | } 8 | } 9 |
  • 新闻
  • 10 |
  • 考试
  • 11 |
    -------------------------------------------------------------------------------- /ExamSystem/Views/News/_manage_sidebar.cshtml: -------------------------------------------------------------------------------- 1 | 
  • 新闻
  • 2 |
  • 考试
  • 3 |
    -------------------------------------------------------------------------------- /ExamSystem/Views/Search/Exams.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | List exams = ViewBag.exams; 3 | int page = ViewBag.page; 4 | int pageNumber = ViewBag.pageNumber; 5 | string keyword = ViewBag.keyword; 6 | ViewBag.Title = keyword + " - 搜索考试"; 7 | Layout = "~/Views/Shared/_layout.cshtml"; 8 | } 9 | @section sidebar { 10 | @Html.Partial("_sidebar") 11 | } 12 |
      13 | @foreach (var exam in exams) 14 | { 15 |
    • 16 |
      17 |
      考试名称
      18 | 19 |
      20 |
      21 |
      考试科目
      22 |
      23 | @SubjectView.GetSubjectById((int)exam.subject).subject_name; 24 |
      25 |
      26 |
      27 |
      考试时间
      28 |
      @exam.start_date.ToLongDateString()
      29 |
      截止时间
      30 |
      @exam.end_date.ToLongDateString()
      31 |
      32 |
      33 |
      考试状态
      34 |
      35 | @{ 36 | DateTime now = DateTime.Now; 37 | bool testing = false; 38 | if (now < exam.start_date) 39 | { 40 | 未开始 41 | } 42 | else if (now > exam.end_date) 43 | { 44 | 已结束 45 | } 46 | else 47 | { 48 | 正在进行 49 | testing = true; 50 | } 51 | } 52 |
      53 |
      54 |
      55 | @if (testing) 56 | { 57 | 进入考试 58 | } 59 | else 60 | { 61 | 进入考试 62 | } 63 |
      64 |
      65 |
    • 66 | } 67 |
    68 |
    69 |
    70 | @if (page > 1) 71 | { 72 | 上一页 73 | } 74 | else 75 | { 76 | 上一页 77 | } 78 |
    第 @page 页
    79 | @if (page < pageNumber) 80 | { 81 | 下一页 82 | } 83 | else 84 | { 85 | 下一页 86 | } 87 |
    -------------------------------------------------------------------------------- /ExamSystem/Views/Search/Groups.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | List groups = ViewBag.groups; 3 | int page = ViewBag.page; 4 | int pageNumber = ViewBag.pageNumber; 5 | string keyword = ViewBag.keyword; 6 | ViewBag.Title = keyword + " - 搜索群组"; 7 | Layout = "~/Views/Shared/_layout.cshtml"; 8 | } 9 | @section sidebar { 10 | @Html.Partial("_sidebar") 11 | } 12 |
      13 |
    • 14 |
      15 |
      群组名
      16 |
      拥有者
      17 |
      人数
      18 |
      加入
      19 |
      20 |
    • 21 | @foreach (var g in groups) 22 | { 23 |
    • 24 |
      25 |
      @g.group_name
      26 |
      @UserView.GetUserById((int)g.owner_uid).name
      27 |
      @g.number
      28 |
      29 | @if (g.allow_join) 30 | { 31 | 加入群组 32 | } 33 | else 34 | { 35 | 加入群组 36 | } 37 |
      38 |
      39 |
    • 40 | } 41 |
    42 |
    43 |
    44 | @if (page > 1) 45 | { 46 | 上一页 47 | } 48 | else 49 | { 50 | 上一页 51 | } 52 |
    第 @page 页
    53 | @if (page < pageNumber) 54 | { 55 | 下一页 56 | } 57 | else 58 | { 59 | 下一页 60 | } 61 |
    -------------------------------------------------------------------------------- /ExamSystem/Views/Search/News.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | List news = ViewBag.news; 3 | int page = ViewBag.page; 4 | int pageNumber = ViewBag.pageNumber; 5 | string keyword = ViewBag.keyword; 6 | ViewBag.Title = keyword + " - 搜索新闻"; 7 | Layout = "~/Views/Shared/_layout.cshtml"; 8 | } 9 | @section sidebar { 10 | @Html.Partial("_sidebar") 11 | } 12 |
      13 | @foreach (var n in news) 14 | { 15 |
    • 16 |
      17 | @n.title 18 |
      19 |
      20 | @n.content.Substring(0, (n.content.Length < 50 ? n.content.Length : 50)) 21 |
      22 |
    • 23 | } 24 |
    25 |
    26 |
    27 | @if (page > 1) 28 | { 29 | 上一页 30 | } 31 | else 32 | { 33 | 上一页 34 | } 35 |
    第 @page 页
    36 | @if (page < pageNumber) 37 | { 38 | 下一页 39 | } 40 | else 41 | { 42 | 下一页 43 | } 44 |
    -------------------------------------------------------------------------------- /ExamSystem/Views/Search/Users.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | List users = ViewBag.users; 3 | int page = ViewBag.page; 4 | int pageNumber = ViewBag.pageNumber; 5 | string keyword = ViewBag.keyword; 6 | string[] ranks = { "已禁用", "普通用户", "教师", "管理员" }; 7 | ViewBag.Title = keyword + " - 搜索用户"; 8 | Layout = "~/Views/Shared/_layout.cshtml"; 9 | } 10 | @section sidebar { 11 | @Html.Partial("_sidebar") 12 | } 13 | 36 |
    37 |
    38 | @if (page > 1) 39 | { 40 | 上一页 41 | } 42 | else 43 | { 44 | 上一页 45 | } 46 |
    第 @page 页
    47 | @if (page < pageNumber) 48 | { 49 | 下一页 50 | } 51 | else 52 | { 53 | 下一页 54 | } 55 |
    -------------------------------------------------------------------------------- /ExamSystem/Views/Search/_sidebar.cshtml: -------------------------------------------------------------------------------- 1 | 
  • 新闻
  • 2 |
  • 考试
  • 3 |
    -------------------------------------------------------------------------------- /ExamSystem/Views/Shared/DisplayTemplates/CanonicalHelperModel.cshtml: -------------------------------------------------------------------------------- 1 | @model MvcSiteMapProvider.Web.Html.Models.CanonicalHelperModel 2 | @using System.Web.Mvc.Html 3 | @using MvcSiteMapProvider.Web.Html.Models 4 | 5 | @if (Model.CurrentNode != null && !string.IsNullOrEmpty(Model.CurrentNode.CanonicalUrl)) { 6 | 7 | } -------------------------------------------------------------------------------- /ExamSystem/Views/Shared/DisplayTemplates/MenuHelperModel.cshtml: -------------------------------------------------------------------------------- 1 | @model MvcSiteMapProvider.Web.Html.Models.MenuHelperModel 2 | @using System.Web.Mvc.Html 3 | @using MvcSiteMapProvider.Web.Html.Models 4 | 5 | -------------------------------------------------------------------------------- /ExamSystem/Views/Shared/DisplayTemplates/MetaRobotsHelperModel.cshtml: -------------------------------------------------------------------------------- 1 | @model MvcSiteMapProvider.Web.Html.Models.MetaRobotsHelperModel 2 | @using System.Web.Mvc.Html 3 | @using MvcSiteMapProvider.Web.Html.Models 4 | 5 | @if (Model.CurrentNode != null && !string.IsNullOrEmpty(Model.CurrentNode.MetaRobotsContent)) { 6 | 7 | } -------------------------------------------------------------------------------- /ExamSystem/Views/Shared/DisplayTemplates/SiteMapHelperModel.cshtml: -------------------------------------------------------------------------------- 1 | @model MvcSiteMapProvider.Web.Html.Models.SiteMapHelperModel 2 | @using System.Web.Mvc.Html 3 | @using MvcSiteMapProvider.Web.Html.Models 4 | 5 |
      6 | @foreach (var node in Model.Nodes) { 7 |
    • @Html.DisplayFor(m => node) 8 | @if (node.Children.Any()) { 9 | @Html.DisplayFor(m => node.Children) 10 | } 11 |
    • 12 | } 13 |
    -------------------------------------------------------------------------------- /ExamSystem/Views/Shared/DisplayTemplates/SiteMapNodeModel.cshtml: -------------------------------------------------------------------------------- 1 | @model MvcSiteMapProvider.Web.Html.Models.SiteMapNodeModel 2 | @using System.Web.Mvc.Html 3 | @using MvcSiteMapProvider.Web.Html.Models 4 | 5 | @if (Model.IsCurrentNode && Model.SourceMetadata["HtmlHelper"].ToString() != "MvcSiteMapProvider.Web.Html.MenuHelper") { 6 | @Model.Title 7 | } else if (Model.IsClickable) { 8 | if (string.IsNullOrEmpty(Model.Description)) 9 | { 10 | @Model.Title 11 | } 12 | else 13 | { 14 | @Model.Title 15 | } 16 | } else { 17 | @Model.Title 18 | } 19 | -------------------------------------------------------------------------------- /ExamSystem/Views/Shared/DisplayTemplates/SiteMapNodeModelList.cshtml: -------------------------------------------------------------------------------- 1 | @model MvcSiteMapProvider.Web.Html.Models.SiteMapNodeModelList 2 | @using System.Web.Mvc.Html 3 | @using MvcSiteMapProvider.Web.Html.Models 4 | 5 |
      6 | @foreach (var node in Model) { 7 |
    • @Html.DisplayFor(m => node) 8 | @if (node.Children.Any()) { 9 | @Html.DisplayFor(m => node.Children) 10 | } 11 |
    • 12 | } 13 |
    -------------------------------------------------------------------------------- /ExamSystem/Views/Shared/DisplayTemplates/SiteMapPathHelperModel.cshtml: -------------------------------------------------------------------------------- 1 | @model MvcSiteMapProvider.Web.Html.Models.SiteMapPathHelperModel 2 | @using System.Web.Mvc.Html 3 | @using System.Linq 4 | @using MvcSiteMapProvider.Web.Html.Models 5 | 6 | @foreach (var node in Model) { 7 | @Html.DisplayFor(m => node); 8 | 9 | if (node != Model.Last()) { 10 | > 11 | } 12 | } -------------------------------------------------------------------------------- /ExamSystem/Views/Shared/DisplayTemplates/SiteMapTitleHelperModel.cshtml: -------------------------------------------------------------------------------- 1 | @model MvcSiteMapProvider.Web.Html.Models.SiteMapTitleHelperModel 2 | @using System.Web.Mvc.Html 3 | @using MvcSiteMapProvider.Web.Html.Models 4 | 5 | @if (Model.CurrentNode != null) {@Model.CurrentNode.Title;} 6 | -------------------------------------------------------------------------------- /ExamSystem/Views/Shared/_layout.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | User user = (User) Session["user"]; 3 | if (user == null && Request.Cookies.Get("uid") != null) 4 | { 5 | user = UserController.LoginWithCookie(Request, Session); 6 | } 7 | } 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | @ViewBag.Title - 在线考试系统 16 | 17 | 18 | 22 | 23 | 24 | 25 | @RenderSection("head", false) 26 | 27 | 28 |
    29 | 77 |
    78 |
    79 | @Html.MvcSiteMap().SiteMapPath() 80 |
    81 | @RenderBody() 82 |
    83 | 103 |
    104 |
    105 | © 2016 - @DateTime.Now.Year, 在线考试系统 106 |
    107 | @if (user == null) 108 | { 109 | @Html.Partial("_signin"); 110 | } 111 |
    112 | 113 | -------------------------------------------------------------------------------- /ExamSystem/Views/Shared/_signin.cshtml: -------------------------------------------------------------------------------- 1 |  24 | -------------------------------------------------------------------------------- /ExamSystem/Views/User/ForgetPassword.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "忘记密码"; 3 | Layout = "~/Views/Shared/_layout.cshtml"; 4 | } 5 | @section sidebar { 6 | @Html.Partial("_not_login_sidebar") 7 | } 8 |
    9 |
    10 |
    11 |
    用户名
    12 |
    13 | 14 |
    15 |
    16 |
    17 |
    电子邮箱
    18 |
    19 | 20 |
    21 |
    22 |
    23 |
    24 | 25 |
    26 |
    27 |
    28 |
    29 | -------------------------------------------------------------------------------- /ExamSystem/Views/User/Login.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "登录"; 3 | Layout = "~/Views/Shared/_layout.cshtml"; 4 | } 5 | @section sidebar { 6 | @Html.Partial("_not_login_sidebar") 7 | } 8 |
    9 |
    10 |
    11 |
    12 |
    13 | 14 |
    15 |
    16 | 17 |
    18 |
    19 |
    20 |
    21 |
    22 |
    23 | 24 |
    25 |
    26 | 27 |
    28 |
    29 |
    30 |
    31 |
    32 |
    33 | 7天内免登录 34 |
    35 |
    36 |
    37 |
    38 |
    39 |
    40 | 用户名或密码错误 41 |
    42 |
    43 |
    44 |
    45 |
    46 |
    47 | 48 |
    49 |
    50 |
    51 | -------------------------------------------------------------------------------- /ExamSystem/Views/User/Profile.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | User user = ViewBag.user; 3 | UserInfo info = ViewBag.info; 4 | User loginedUser = ViewBag.loginedUser; 5 | string[] ranks = { "已禁用", "普通用户", "教师", "管理员" }; 6 | ViewBag.Title = user.name + " - 用户资料"; 7 | Layout = "~/Views/Shared/_layout.cshtml"; 8 | } 9 | @section sidebar { 10 | @if (loginedUser.uid == user.uid || loginedUser.rank == (int)UserRank.ADMINISTATOR) 11 | { 12 |
  • 编辑资料
  • 13 | } 14 | @if (loginedUser.uid != user.uid) 15 | { 16 |
  • 发消息
  • 17 | } 18 | @Html.Partial("_sidebar") 19 | } 20 |
    21 |
    22 |
    23 | UID: 24 |
    25 |
    26 | @user.uid 27 |
    28 |
    29 |
    30 |
    31 | 用户名: 32 |
    33 |
    34 | @user.username 35 |
    36 |
    37 |
    38 |
    39 | 昵称: 40 |
    41 |
    42 | @user.name 43 |
    44 |
    45 |
    46 |
    47 | 用户权限: 48 |
    49 |
    50 | @ranks[user.rank] 51 |
    52 |
    53 |
    54 |
    55 | 性别: 56 |
    57 |
    58 | @info.sex 59 |
    60 |
    61 |
    62 |
    63 | 生日: 64 |
    65 |
    66 | @info.birthday.ToLongDateString() 67 |
    68 |
    69 | @if (loginedUser.uid == user.uid || loginedUser.rank == (int)UserRank.ADMINISTATOR) 70 | { 71 |
    72 |
    73 | 注册时间: 74 |
    75 |
    76 | @info.reg_date.ToLongDateString() @info.reg_date.ToLongTimeString() 77 |
    78 |
    79 |
    80 |
    81 | 上次登录时间: 82 |
    83 |
    84 | @user.login_date.ToLongDateString() @user.login_date.ToLongTimeString() 85 |
    86 |
    87 |
    88 |
    89 | 邮箱: 90 |
    91 |
    92 | @info.email 93 |
    94 |
    95 |
    96 |
    97 | 邮箱验证状态: 98 |
    99 |
    100 | @(info.email_valid ? "已验证" : "未验证") 101 |
    102 |
    103 |
    104 |
    105 | 联系号码: 106 |
    107 |
    108 | @info.telephone 109 |
    110 |
    111 |
    112 |
    113 | 地址: 114 |
    115 |
    116 | @info.address 117 |
    118 |
    119 | } 120 |
    121 |
    122 | 个人介绍: 123 |
    124 |
    125 | @info.description 126 |
    127 |
    128 |
    -------------------------------------------------------------------------------- /ExamSystem/Views/User/Recover.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | User user = ViewBag.user; 3 | string code = ViewBag.code; 4 | ViewBag.Title = "恢复账户"; 5 | Layout = "~/Views/Shared/_layout.cshtml"; 6 | } 7 | @section sidebar { 8 | @Html.Partial("_not_login_sidebar") 9 | } 10 |
    11 |
    12 | 13 | 14 |
    15 |
    新密码
    16 |
    17 | 18 |
    19 |
    20 |
    21 |
    确认密码
    22 |
    23 | 24 |
    25 |
    26 |
    27 |
    28 | 29 |
    30 |
    31 |
    32 |
    33 | -------------------------------------------------------------------------------- /ExamSystem/Views/User/Register.cshtml: -------------------------------------------------------------------------------- 1 |  2 | @{ 3 | ViewBag.Title = "注册"; 4 | Layout = "~/Views/Shared/_layout.cshtml"; 5 | } 6 | @section sidebar { 7 | @Html.Partial("_not_login_sidebar") 8 | } 9 |
    10 |
    11 |
    12 |
    13 |
    14 | 15 |
    16 |
    17 | 18 |
    19 |
    20 |
    21 |
    22 |
    23 |
    24 | 25 |
    26 |
    27 | 28 |
    29 |
    30 |
    31 |
    32 |
    33 |
    34 | 35 |
    36 |
    37 | 38 |
    39 |
    40 |
    41 |
    42 |
    43 |
    44 | 45 |
    46 |
    47 | 48 |
    49 |
    50 |
    51 |
    52 |
    53 |
    54 | 55 |
    56 |
    57 | 58 |
    59 |
    60 |
    61 |
    62 |
    63 |
    64 | 注册失败,请稍后重试或联系管理员。 65 |
    66 |
    67 |
    68 |
    69 |
    70 |
    71 | 72 |
    73 |
    74 |
    75 | -------------------------------------------------------------------------------- /ExamSystem/Views/User/Result.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | List results = ViewBag.results; 3 | int totalPageNumber = ViewBag.pageNumber; 4 | int page = ViewBag.page; 5 | ViewBag.Title = "成绩浏览"; 6 | Layout = "~/Views/Shared/_layout.cshtml"; 7 | } 8 | @section sidebar { 9 | @Html.Partial("_sidebar") 10 | } 11 |
      12 |
    • 13 |
      14 |
      考试名称
      15 |
      考试科目
      16 |
      分数
      17 |
      18 |
    • 19 | @foreach (var result in results) 20 | { 21 |
    • 22 |
      23 |
      @ExamView.GetExamById((int)result.eid).title
      24 |
      @ExamView.GetExamById((int)result.eid).Subject1.subject_name
      25 | 26 | @if (result.score == -1) 27 | { 28 |
      未阅卷
      29 | } 30 | else 31 | { 32 |
      @result.score
      33 | } 34 |
      35 |
    • 36 | } 37 |
    38 |
    39 | @if (page > 1) 40 | { 41 | 上一页 42 | } 43 | else 44 | { 45 | 上一页 46 | } 47 |
    第 @page 页
    48 | @if (page < totalPageNumber) 49 | { 50 | 下一页 51 | } 52 | else 53 | { 54 | 下一页 55 | } 56 |
    -------------------------------------------------------------------------------- /ExamSystem/Views/User/Setting.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | User user = ViewBag.user; 3 | UserInfo info = ViewBag.info; 4 | ViewBag.Title = "个人设置"; 5 | Layout = "~/Views/Shared/_layout.cshtml"; 6 | } 7 | @section sidebar { 8 |
  • 编辑资料
  • 9 | @Html.Partial("_sidebar") 10 | } 11 |
    12 |
    13 |

    修改邮箱

    14 |
    15 |
    电子邮箱
    16 |
    17 | 18 |
    19 |
    20 |
    21 |
    22 | 23 |
    24 |
    25 |
    26 |
    27 |
    28 |

    修改密码

    29 |
    30 |
    旧密码
    31 |
    32 | 33 |
    34 |
    35 |
    36 |
    新密码
    37 |
    38 | 39 |
    40 |
    41 |
    42 |
    确认密码
    43 |
    44 | 45 |
    46 |
    47 |
    48 |
    49 | 50 |
    51 |
    52 |
    53 |
    54 | -------------------------------------------------------------------------------- /ExamSystem/Views/User/_not_login_sidebar.cshtml: -------------------------------------------------------------------------------- 1 | 
  • 登录
  • 2 |
  • 注册
  • 3 |
  • 忘记密码
  • 4 |
    5 |
  • 新闻
  • 6 |
  • 考试
  • 7 |
    -------------------------------------------------------------------------------- /ExamSystem/Views/User/_sidebar.cshtml: -------------------------------------------------------------------------------- 1 | 
  • 新闻
  • 2 |
  • 考试
  • 3 |
    -------------------------------------------------------------------------------- /ExamSystem/Views/web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
    6 |
    7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /ExamSystem/Web.Debug.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | -------------------------------------------------------------------------------- /ExamSystem/Web.Release.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | -------------------------------------------------------------------------------- /ExamSystem/Web.config: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 |
    9 | 10 |
    11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /ExamSystem/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghosind/ExamSystem/ee8103a8ce26b30b9fea97258fb3c227200703d2/ExamSystem/favicon.ico -------------------------------------------------------------------------------- /ExamSystem/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghosind/ExamSystem/ee8103a8ce26b30b9fea97258fb3c227200703d2/ExamSystem/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /ExamSystem/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghosind/ExamSystem/ee8103a8ce26b30b9fea97258fb3c227200703d2/ExamSystem/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /ExamSystem/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghosind/ExamSystem/ee8103a8ce26b30b9fea97258fb3c227200703d2/ExamSystem/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /ExamSystem/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghosind/ExamSystem/ee8103a8ce26b30b9fea97258fb3c227200703d2/ExamSystem/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /ExamSystem/install/ExamSystem.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [User] ( 2 | [uid] INT PRIMARY KEY IDENTITY(1,1), 3 | [username] VARCHAR(64) UNIQUE NOT NULL, 4 | [password] CHAR(128) NOT NULL, 5 | [name] VARCHAR(32) NOT NULL, 6 | [rank] INT NOT NULL DEFAULT 0, 7 | [login_date] DATETIME NOT NULL DEFAULT GETDATE() /* date of last login */ 8 | ); 9 | 10 | CREATE TABLE [UserInfo] ( 11 | [uid] INT REFERENCES [user]([uid]), 12 | [sex] CHAR(2) NOT NULL DEFAULT '男', 13 | [birthday] DATETIME NOT NULL DEFAULT '1970-01-01', 14 | [telephone] VARCHAR(11), 15 | [email] VARCHAR(128) UNIQUE NOT NULL , 16 | [email_valid] BIT NOT NULL DEFAULT 0, /* valid status of email */ 17 | [address] VARCHAR(128), 18 | [description] VARCHAR(256), 19 | [reg_date] DATETIME NOT NULL DEFAULT GETDATE() /* register date */ 20 | ); 21 | 22 | CREATE TABLE [ForgetPassword] ( 23 | [uid] INT REFERENCES [User]([uid]), 24 | [code] char(128) NOT NULL 25 | ); 26 | 27 | CREATE TABLE [Group] ( 28 | [gid] INT PRIMARY KEY IDENTITY(1,1), 29 | [group_name] VARCHAR(64) NOT NULL, 30 | [owner_uid] INT REFERENCES [user]([uid]), 31 | [number] INT NOT NULL DEFAULT 0, 32 | [allow_join] BIT NOT NULL DEFAULT 1, 33 | [allow_quit] BIT NOT NULL DEFAULT 1 34 | ); 35 | 36 | CREATE TABLE [GroupMember] ( 37 | [gid] INT REFERENCES [group]([gid]), 38 | [uid] INT REFERENCES [user]([uid]), 39 | [rank] INT NOT NULL DEFAULT 0 40 | ); 41 | 42 | CREATE TABLE [Message] ( 43 | [mid] INT PRIMARY KEY IDENTITY(1,1), 44 | [sender] INT REFERENCES [user]([uid]), 45 | [receiver] INT REFERENCES [user]([uid]), 46 | [title] VARCHAR(128) NOT NULL, 47 | [content] TEXT NOT NULL, 48 | [send_date] DATETIME NOT NULL, 49 | [read] BIT NOT NULL DEFAULT 0 50 | ); 51 | 52 | CREATE TABLE [News] ( 53 | [nid] INT PRIMARY KEY IDENTITY(1,1), 54 | [publisher] INT REFERENCES [user]([uid]), 55 | [title] VARCHAR(256) NOT NULL, 56 | [content] TEXT NOT NULL, 57 | [date] DATETIME NOT NULL 58 | ); 59 | 60 | CREATE TABLE [Subject] ( 61 | [sid] INT PRIMARY KEY IDENTITY(1,1), 62 | [subject_name] VARCHAR(128) UNIQUE NOT NULL 63 | ); 64 | 65 | CREATE TABLE [Section] ( 66 | [kid] INT PRIMARY KEY IDENTITY(1,1), 67 | [section_name] VARCHAR(256) NOT NULL, 68 | [sid] INT REFERENCES [subject]([sid]) 69 | ); 70 | 71 | CREATE TABLE [Questions] ( 72 | [qid] INT PRIMARY KEY IDENTITY(1,1), 73 | [type] INT NOT NULL, 74 | [kid] INT REFERENCES [Section]([kid]), 75 | [suggest_difficulty] FLOAT NOT NULL DEFAULT 0.5, 76 | [difficulty] FLOAT NOT NULL DEFAULT 0.5, 77 | [number] INT NOT NULL DEFAULT 0 78 | ); 79 | 80 | CREATE TABLE [ChoiceQuestions] ( 81 | [qid] INT REFERENCES [questions]([qid]), 82 | [content] TEXT NOT NULL, 83 | [choice_num] INT NOT NULL DEFAULT 4, 84 | [choice_1] TEXT NOT NULL, 85 | [choice_2] TEXT NOT NULL, 86 | [choice_3] TEXT, 87 | [choice_4] TEXT, 88 | [answer] INT NOT NULL 89 | ); 90 | 91 | CREATE TABLE [FillQuestions] ( 92 | [qid] INT REFERENCES [questions]([qid]), 93 | [content] TEXT NOT NULL, 94 | [answer] TEXT NOT NULL 95 | ); 96 | 97 | CREATE TABLE [DiscussQuestions] ( 98 | [qid] INT REFERENCES [questions]([qid]), 99 | [content] TEXT NOT NULL, 100 | [answer] TEXT NOT NULL 101 | ); 102 | 103 | CREATE TABLE [Exams] ( 104 | [eid] INT PRIMARY KEY IDENTITY(1,1), 105 | [title] VARCHAR(128) NOT NULL, 106 | [subject] INT REFERENCES [Subject]([sid]), 107 | [time] INT NOT NULL DEFAULT 60, 108 | [start_date] DATETIME NOT NULL, 109 | [end_date] DATETIME NOT NULL, 110 | [exam_path] VARCHAR(128) NOT NULL, /* xml file path of exam */ 111 | [answer_path] VARCHAR(128) NOT NULL, 112 | [must_take] BIT NOT NULL DEFAULT 0, 113 | [public] BIT NOT NULL DEFAULT 1 114 | ); 115 | 116 | CREATE TABLE [ExamsGroup] ( 117 | [eid] INT REFERENCES [exams]([eid]), 118 | [gid] INT REFERENCES [Group]([gid]) /* set group id to specify a group to take the exam. 0 means every one can take this exam and negative number means nobody can take the exam. */ 119 | ); 120 | 121 | CREATE TABLE [Result] ( 122 | [uid] INT REFERENCES [user]([uid]), 123 | [eid] INT REFERENCES [exams]([eid]), 124 | [answer] VARCHAR(128) NOT NULL, /* xml file path of answers */ 125 | [reviewer] INT REFERENCES [user]([uid]), 126 | [score] INT NOT NULL DEFAULT -1 /* -1 means the answers is unreviewed */ 127 | ); 128 | 129 | 130 | INSERT INTO [User]([username], [password], [name], [rank]) VALUES(@username, @password, @nickname, 3); 131 | 132 | INSERT INTO [UserInfo]([uid], [email]) VALUES(1, @email); -------------------------------------------------------------------------------- /ExamSystem/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Chen Su 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ExamSystem 2 | 3 | 一个基于ASP.Net MVC开发的简单的考试管理系统。本项目已不再继续开发与维护,但欢迎提PR完善本项目,已知的问题与改进方向在Todo中提及。 4 | 5 | ## 环境要求 6 | 7 | - Visual Studio 2015 8 | - SQL Server 2008 R2 9 | 10 | ## 项目特点 11 | 12 | - 基于Bootstrap的UI设计 13 | - 用户、群组管理功能 14 | - 实现命卷、答题、阅卷功能 15 | - 站内信、公告系统 16 | 17 | ## Todos 18 | 19 | - 响应式设计 20 | - 前后端分离 21 | - 修复部分页面出现的空指针异常 22 | - 修复错误的逻辑 23 | - 增加docker支持 24 | - 增加多语言支持 25 | - 支持对更多种类数据库的支持 26 | - 升级至.Net Core 27 | - ... 28 | 29 | ## 开源许可 30 | 31 | 本项目使用MIT开源许可。 32 | --------------------------------------------------------------------------------