public void ProcessRequest(HttpContext context) { lms_Entities db = new ClientDBEntities(); string command = context.Request.Form["command"]?.ToUpper(); string version = context.Request.Form["version"]; string[] session = context.Request.Form["session_id"].ToString().Split('|'); int userId = int.Parse(session[0]); int courseId = int.Parse(session[1]); int assignmentId = int.Parse(session[2]); const string CRLF = "\r\n"; string str = ""; switch (command) { case "GETPARAM": db.Course_ScormValueSet(userId, assignmentId, courseId, "SET-STARTDATE", null); //this forces a set of "startDate" if necessary Course_StartupDefaults_Result initInfo = db.Course_StartupDefaults(userId, assignmentId, courseId).FirstOrDefault(); str = "error=0" + CRLF + "error_text=successful" + CRLF + "version=" + version + CRLF + "aicc_data=[core]" + CRLF + "Student_ID=" + userId + CRLF + "Student_Name=" + initInfo.student_name + CRLF + "Output_file=" + CRLF + "Credit=c" + CRLF + "Lesson_Location=" + initInfo.lesson_location + CRLF + "Lesson_Status=" + initInfo.lesson_status + CRLF + "path=" + CRLF + "Score=" + initInfo.maxScore + CRLF + "Time=00:00:00" + CRLF + "[Core_Lesson]" + CRLF + initInfo.suspend_data; //+ initInfo.totalTimeUsage Log.Info("Aicc GETPARAM return:" + str); break; case "PUTPARAM": AICCDataReader aiccData = new AICCDataReader(context.Request.Form["aicc_data"]); //data looks like this: //"[core]\r\nlesson_status=i\r\nlesson_location=m01_s01_t01~m01_s01_t01\r\ntime=00:00:03\r\n" string lesson_location = aiccData.GetKeyValue("lesson_location"); string lesson_status = aiccData.GetKeyValue("lesson_status"); string score = aiccData.GetKeyValue("score"); string suspend_data = aiccData.GetKeyValue("[core_lesson]"); //take only the first 99 hours of session time.. or SQL db will cry string sessionTime = aiccData.GetKeyValue("time"); string[] tmp = sessionTime.Split(':'); if (tmp[0].Length == 4) { tmp[0] = tmp[0].Substring(2); sessionTime = string.Join(":", tmp); } db.Course_ScormValueSet(userId, assignmentId, courseId, "CMI.CORE.LESSON_STATUS", lesson_status); db.Course_ScormValueSet(userId, assignmentId, courseId, "CMI.CORE.LESSON_LOCATION", lesson_location); if (score.Length > 0) { db.Course_ScormValueSet(userId, assignmentId, courseId, "CMI.CORE.SCORE.RAW", score); } db.Course_ScormValueSet(userId, assignmentId, courseId, "CMI.CORE.SESSION_TIME", sessionTime); db.Course_ScormValueSet(userId, assignmentId, courseId, "CMI.SUSPEND_DATA", suspend_data); //'build response str = "error=0" + CRLF + "error_text=Successful" + CRLF + "version=" + version; break; case "PUTINTERACTIONS": //IGNORED... send "sure, ok" messsage str = "error=0" + CRLF + "error_text=Successful" + CRLF + "version=" + version; break; case "EXITAU": //IGNORED... send "sure, ok" messsage str = "error=0" + CRLF + "error_text=Successful" + CRLF + "version=" + version; break; default: Log.Error("AICC command not implemented:" + command, false); break; } context.Response.ContentType = "text/plain"; context.Response.Cache.SetCacheability(HttpCacheability.NoCache); //sets: Cache-Control: no-cache, Expires: -1, Pragma: no-cache context.Response.Write(str); context.Response.End(); }
public void ProcessRequest(HttpContext context) { int?assignmentId = Utilities.TryToParseAsInt(context.Request.QueryString["aid"]); int?courseId = Utilities.TryToParseAsInt(context.Request.QueryString["cid"]); int userId; //set UserID coming from course primarily if (context.Request.QueryString["uid"] == null) { userId = LmsUser.UserId; } else { userId = (int)Utilities.TryToParseAsInt(context.Request.QueryString["uid"]); } context.Response.CacheControl = "no-cache"; // must never be cached context.Response.ContentType = "application/json; charset=utf-8"; //set json as default response lms_Entities db = new ClientDBEntities(); //call functions switch (context.Request.QueryString["m"].ToUpper()) { case "GET_COURSE_STATS": //----------------------------------------------- // displays data in curriculum page - per course //----------------------------------------------- if (userId == 0) { Log.Error("User:UNKNOWN SESSION called GET_COURSE_STATS function"); context.Response.Write("NO_SESSION"); } else { Course_BasicInfo_Result res = db.Course_BasicInfo(assignmentId, courseId, userId).FirstOrDefault(); context.Response.Write( "{" + @"""startDate"":" + (res.startDate == null ? "null" : @"""" + String.Format("{0:d}", res.startDate) + @"""") + "," + @"""completedDate"":" + (res.completedDate == null ? "null" : "\"" + String.Format("{0:d}", res.completedDate) + @"""") + "," + @"""maxScore"":" + (res.maxScore == null ? "null" : res.maxScore.ToString()) + "}" ); } break; case "SCORM_COURSE_INITIAL_DEFAULTS": //load all initial scorm values and send to scorm.js manager Log.Info("User " + userId + " launched course:" + courseId + ", assignmentId:" + assignmentId); db.Course_ScormValueSet(userId, assignmentId, courseId, "SET-STARTDATE", null); //this forces a set of "startDate" if necessary Course_StartupDefaults_Result initInfo = db.Course_StartupDefaults(userId, assignmentId, courseId).FirstOrDefault(); string suspend_data = initInfo.suspend_data?.Replace("\"", "\\\""); //encode double quotes string total_time = initInfo.totalTimeUsage == null ? "0000:00:00.00" : String.Format("00{0:%hh}:{0:%mm}:{0:%s}", initInfo.totalTimeUsage); context.Response.Write( @"{""cmi"":{" + @"""launch_data"":""""," + @"""interactions"": {""_count"": 0}," + @"""student_data"": {""mastery_score"": """"}," + @"""core"":{" + @"""total_time"":""" + total_time + @"""," + @"""student_id"":" + userId + "," + @"""lesson_mode"":""normal""," + @"""lesson_status"":""" + initInfo.lesson_status + @"""," + @"""lesson_location"":""" + initInfo.lesson_location + @"""," + @"""student_name"":""" + initInfo.student_name + @"""," + @"""score"": {" + @"""raw"":" + (initInfo.maxScore == null ? @"""""" : initInfo.maxScore.ToString()) + "}" + @"}," + @"""suspend_data"":""" + suspend_data + @"""" + "}" + "}" ); break; case "KEEP_SESSION_ALIVE": context.Response.ContentType = "text/plain"; //override to plain text context.Response.Write("<html>"); context.Response.Write("<head>"); context.Response.Write("<meta http-equiv=\"refresh\" content=\"" + context.Request.QueryString["secs"] + "\">"); //every 5 minutes (300 seconds) context.Response.Write("<meta http-equiv=\"pragma\" content=\"no-cache\">"); context.Response.Write("<meta http-equiv=\"expires\" content=\"0\">"); context.Response.Write("</head>"); context.Response.Write("<body></body>"); context.Response.Write("</html>"); break; case "CMI.INTERACTIONS.0.STUDENT_RESPONSE": //THIS MESSAGE IGNORED IN THIS PARTICULAR LMS INSTANCE context.Response.Write("{\"result\":true}"); break; case "CMI.CORE.LESSON_STATUS": Log.Info("User " + userId + " status set to:\"" + context.Request.Form["data"] + "\", course:" + courseId + ", assignmentId:" + assignmentId); if (context.Request.QueryString["dir"] == "set") { //allowed values:passed, completed, failed, incomplete, browsed, not attempted int?affected = db.Course_ScormValueSet(userId, assignmentId, courseId, "CMI.CORE.LESSON_STATUS", context.Request.Form["data"]).FirstOrDefault(); context.Response.Write(@"{""result"":" + (affected == 1 ? "true" : "false") + "}"); } else { context.Response.Write("{\"result\":false}"); } break; case "CMI.CORE.LESSON_LOCATION": if (context.Request.QueryString["dir"] == "set") { int?affected = db.Course_ScormValueSet(userId, assignmentId, courseId, "CMI.CORE.LESSON_LOCATION", context.Request.Form["data"]).FirstOrDefault(); context.Response.Write(@"{""result"":" + (affected == 1 ? "true" : "false") + "}"); } else { context.Response.Write("{\"result\":false}"); } break; case "CMI.SUSPEND_DATA": if (context.Request.QueryString["dir"] == "set") { int?affected = db.Course_ScormValueSet(userId, assignmentId, courseId, "CMI.SUSPEND_DATA", context.Request.Form["data"]).FirstOrDefault(); context.Response.Write(@"{""result"":" + (affected == 1 ? "true" : "false") + "}"); } else { context.Response.Write("{\"result\":false}"); } break; case "CMI.CORE.SESSION_TIME": if (context.Request.QueryString["dir"] == "set") { string session_time = context.Request.Form["data"]; //NOTE: session time comes in a format like "0000:00:02.75"... 4 digits for hour if (session_time.Length == 0) { session_time = null; } else { //take only the first 99 hours string[] tmp = session_time.Split(':'); if (tmp[0].Length == 4) { tmp[0] = tmp[0].Substring(2); session_time = string.Join(":", tmp); } } int?affected = db.Course_ScormValueSet(userId, assignmentId, courseId, "CMI.CORE.SESSION_TIME", session_time).FirstOrDefault(); context.Response.Write(@"{""result"":" + (affected == 1 ? "true" : "false") + "}"); } else { context.Response.Write("{\"result\": false}"); } break; case "CMI.CORE.SCORE.RAW": Log.Info("Score received:\"" + context.Request.Form["data"] + "\" for course id:" + courseId + ", userId:" + userId + ", assignmentId:" + assignmentId); if (context.Request.QueryString["dir"] == "set") { double?score = Utilities.TryToParseAsDouble(context.Request.Form["data"]); if (score == null) { Log.Info("Score ignored."); context.Response.Write("{\"result\": true}"); //just to keep the course happy } else { int?affected = db.Course_ScormValueSet(userId, assignmentId, courseId, "CMI.CORE.SCORE.RAW", context.Request.Form["data"]).FirstOrDefault(); Log.Info("Score saved:\"" + context.Request.Form["data"] + "\" for course id:" + courseId + ", userId:" + userId + ", assignmentId:" + assignmentId + ", records changed=" + affected); context.Response.Write(@"{""result"":" + (affected == 1 ? "true" : "false") + "}"); } } else { context.Response.Write("{\"result\":false}"); } break; case "CMI.CORE.EXIT": context.Response.Write("{\"result\": true}"); break; case "COURSE_LAUNCH_PARAMS": Course crs = db.Courses.Where(c => c.courseId == courseId).FirstOrDefault(); context.Response.Write( "{" + "\"title\":\"" + crs.title + "\"," + "\"url\":\"" + crs.url + "\"," + "\"type\":" + crs.type + "," + "\"width\":" + (crs.browserWidth == null? "null": crs.browserWidth.ToString()) + "," + "\"height\":" + (crs.browserHeight == null ? "null" : crs.browserHeight.ToString()) + "}" ); break; default: Log.Info("User:"******" unknown message \"" + context.Request.QueryString["m"] + "\", course:" + courseId + ", assignmentId:" + assignmentId); context.Response.Write("{\"result\":false}"); break; } }