/// <summary> /// Allows the app to take action when the session is ending. /// </summary> public void ProcessSessionEnd(LearningSession session, ref string messageTitle, ref string message) { // Session ending results in message shown to the user. if (session.View == SessionView.Execute) { StoredLearningSession slsSession = session as StoredLearningSession; if (slsSession != null) { // The rollup and/or sequencing process may have changed the state of the attempt. If so, there are some cases // that cannot continue so show an error message. switch (slsSession.AttemptStatus) { case AttemptStatus.Abandoned: messageTitle = IUDICO.TestingSystem.Localization.getMessage("HID_SessionAbandonedTitle"); message = IUDICO.TestingSystem.Localization.getMessage("FRM_ExecuteViewAbandonedSessionMsg"); break; case AttemptStatus.Completed: messageTitle = IUDICO.TestingSystem.Localization.getMessage("HID_SessionCompletedTitle"); message = IUDICO.TestingSystem.Localization.getMessage("FRM_ExecuteViewCompletedSessionMsg"); break; case AttemptStatus.Suspended: messageTitle = IUDICO.TestingSystem.Localization.getMessage("HID_SessionSuspendedTitle"); message = IUDICO.TestingSystem.Localization.getMessage("FRM_ExecuteViewSuspendedSessionMsg"); break; } } } }
/// <summary> /// Delegate implementation to allow the frameset to take action on a session view request. This allows SLK and /// BWP to have different behavior and messages about which requests are not valid. /// </summary> public bool ProcessViewRequest(SessionView view, LearningSession session) { Completed = false; switch (view) { case SessionView.Execute: { StoredLearningSession slsSession = session as StoredLearningSession; if (slsSession != null) { if (slsSession.AttemptStatus == AttemptStatus.Completed) { RegisterError(ResHelper.GetMessage(IUDICO.TestingSystem.Localization.getMessage("FRM_InvalidAttemptStatusForViewTitle")), ResHelper.GetMessage(IUDICO.TestingSystem.Localization.getMessage("FRM_ExecuteViewCompletedSessionMsg")), false); Completed = true; return false; } else if (slsSession.AttemptStatus == AttemptStatus.Abandoned) { RegisterError(ResHelper.GetMessage(IUDICO.TestingSystem.Localization.getMessage("FRM_InvalidAttemptStatusForViewTitle")), ResHelper.GetMessage(IUDICO.TestingSystem.Localization.getMessage("FRM_ExecuteViewAbandonedSessionMsg")), false); return false; } } } break; case SessionView.Review: // BWP does not provide review view RegisterError(ResHelper.GetMessage(IUDICO.TestingSystem.Localization.getMessage("FRM_ViewNotSupportedTitle")), ResHelper.GetMessage(IUDICO.TestingSystem.Localization.getMessage("FRM_ReviewViewNotSupportedMsg")), false); break; case SessionView.RandomAccess: RegisterError(ResHelper.GetMessage(IUDICO.TestingSystem.Localization.getMessage("FRM_ViewNotSupportedTitle")), ResHelper.GetMessage(IUDICO.TestingSystem.Localization.getMessage("FRM_RAViewNotSupportedMsg")), false); break; } return true; }
public static void AppendContentFrameDetails(LearningSession session, StringBuilder sb) { // The URL for attempt-based content frames is: // http://<...basicWebApp>/Content.aspx/<view>/<attemptId>/otherdata/ // the otherdata depends on the view sb.Append(String.Format(CultureInfo.CurrentCulture, "/{0}", Convert.ToInt32(session.View))); StoredLearningSession slsSession = session as StoredLearningSession; sb.AppendFormat("/{0}", slsSession.AttemptId.GetKey().ToString()); }
[SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods")] // parameters are validated public void ProcessPageLoad(PackageStore packageStore, TryGetViewInfo TryGetViewInfo, TryGetAttemptInfo TryGetAttemptInfo, ProcessViewRequest ProcessViewRequest) { // These should never be a problem, however fxcop complains about them. FramesetUtil.ValidateNonNullParameter("TryGetViewInfo", TryGetViewInfo); FramesetUtil.ValidateNonNullParameter("TryGetAttemptInfo", TryGetAttemptInfo); FramesetUtil.ValidateNonNullParameter("ProcessViewRequest", ProcessViewRequest); FramesetUtil.ValidateNonNullParameter("packageStore", packageStore); // Session information that may be required SessionView view; AttemptItemIdentifier attemptId; // not required for all views // Get View information. It determines what else to look for. if (!TryGetViewInfo(true, out view)) return; // Based on View, request other information switch (view) { case SessionView.Execute: { // AttemptId is required if (!TryGetAttemptInfo(true, out attemptId)) return; // Create the session m_session = new StoredLearningSession(view, attemptId, packageStore); StoredLearningSession slsSession = m_session as StoredLearningSession; if (!ProcessViewRequest(SessionView.Execute, slsSession)) { if (slsSession.AttemptStatus == AttemptStatus.Completed) { } return; } // If the attempt id appeared valid (that is, it was numeric), but does not represent a valid // attempt, the call to access AttemptStatus on the session will trigger an InvalidOperationException // containing a message for the user that the attempt id was not valid. switch (slsSession.AttemptStatus) { case AttemptStatus.Abandoned: { // Can't do execute view on abandoned sessions. The application should have handled this // in the ProcessViewRequest. return; } case AttemptStatus.Active: { // Check if it's started. If not, try starting it and forcing selection of a current activity. if (!slsSession.HasCurrentActivity) { try { slsSession.Start(false); slsSession.CommitChanges(); } catch (SequencingException) { // Intentionally ignored. This means it was either already started or could not // select an activity. In either case, just let the content frame ask the user to // deal with selecting an activity. } } else { // If the current activity is not active, then it's possible the frameset was removed from the // user and the content suspended the current activity. In that case, we do this little trick // and try suspending all the activities and then resuming them. The resume will simply resume // all the activities between the current activity and the root. Other suspended activities // will not be affected. if (!slsSession.CurrentActivityIsActive) { slsSession.Suspend(); slsSession.Resume(); slsSession.CommitChanges(); } } } break; case AttemptStatus.Completed: { // Can't do execute view on completed sessions. The application should have handled this in the // ProcessViewRequest. return; } case AttemptStatus.Suspended: { // Resume it slsSession.Resume(); slsSession.CommitChanges(); } break; default: break; } } break; case SessionView.RandomAccess: { // AttemptId is required if (!TryGetAttemptInfo(true, out attemptId)) return; StoredLearningSession slsSession = new StoredLearningSession(SessionView.RandomAccess, attemptId, packageStore); m_session = slsSession; if (!ProcessViewRequest(SessionView.RandomAccess, slsSession )) return; // Move to the first activity with a resource. PostableFrameHelper.MoveToNextActivity(m_session); } break; case SessionView.Review: { // AttemptId is required if (!TryGetAttemptInfo(true, out attemptId)) return; // Create the session StoredLearningSession slsSession = new StoredLearningSession(view, attemptId, packageStore); m_session = slsSession; if (!ProcessViewRequest(SessionView.Review, m_session)) return; // Access a property. If the user doesn't have permission, this will throw exception if (m_session.HasCurrentActivity) { // This is good. The 'if' statement is here to make compiler happy. } } break; } }
/// <summary> /// Gets the title to display in the session. /// </summary> public PlainTextString GetSessionTitle(LearningSession session) { return new PlainTextString(session.Title); }
[SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods")] // parameter is validated protected static void MoveToActivity(LearningSession session, long activityId) { FramesetUtil.ValidateNonNullParameter("session", session); session.MoveToActivity(activityId); // If this is random access view, make sure to move to an activity that has a resource. if ((session.View == SessionView.RandomAccess) && (session.CurrentActivityResourceType == ResourceType.None)) { MoveToNextActivity(session); } }
[SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods")] // parameter is validated protected static void MoveToPreviousActivity(LearningSession session) { session.MoveToPrevious(); // If this is RA view, make sure the activity has a resource if (session.View == SessionView.RandomAccess) { while (session.CurrentActivityResourceType == ResourceType.None) { session.MoveToPrevious(); } } }
protected static bool ProcessNavigationRequests(LearningSession session) { if (session.View != SessionView.Execute) return false; // View is execute, so call the method return session.ProcessNavigationRequests(); }
/// <summary> /// Delegate to allow BWP to take action after posted data is processed. /// </summary> /// <param name="session"></param> public void ProcessPostedDataComplete(LearningSession session) { // Do nothing }
/// <summary> /// Allow application to process posted data. /// </summary> public bool ProcessPostedData(LearningSession session, HttpRequest request, Dictionary<string, HttpPostedFile> fileCollection) { // Verify that posted files map to files that actually exist. HttpFileCollection files = request.Files; StringBuilder messageBuffer = new StringBuilder(); bool firstError = true; foreach (string fileId in files) { HttpPostedFile postedFile = files[fileId]; string filename = postedFile.FileName; // If contentLength == 0 and fileName == emptyString, then this is probably a posting after // the initial file posting. (For instance, to remove the file.) This is a valid file and is added to the // collection. // If the contentLength == 0 and fileName != emptyString, then user is trying to attach a file // that has no contents. This is not allowed. if ((String.IsNullOrEmpty(filename) && (postedFile.ContentLength == 0)) || (!String.IsNullOrEmpty(filename) && (postedFile.ContentLength > 0))) { fileCollection.Add(fileId, postedFile); } else { // This is not a valid file. if (firstError) { messageBuffer.Append(IUDICO.TestingSystem.Localization.getMessage("CON_AttachedFileDoesNotExistHtml")); messageBuffer.Append("\r\n<br><br><ul>\r\n"); firstError = false; } messageBuffer.AppendFormat("<li>{0}</li>", HttpUtility.HtmlEncode(filename)); } } if (!firstError) { messageBuffer.Append("</ul><br>"); messageBuffer.Append(IUDICO.TestingSystem.Localization.getMessage("CON_FileAttachmentErrorEndHtml")); // Add information for the 'Continue' link JScriptString js = new JScriptString(ResHelper.FormatInvariant("API_GetFramesetManager().DoChoice(\"{0}\");", FramesetUtil.GetStringInvariant(session.CurrentActivityId))); messageBuffer.AppendFormat(CultureInfo.CurrentCulture, "<br><br><a href='{0}' >{1}</a>", js.ToJavascriptProtocol(), HttpUtility.HtmlEncode(IUDICO.TestingSystem.Localization.getMessage("HID_ReloadCurrentContent"))); RegisterError(IUDICO.TestingSystem.Localization.getMessage("CON_FileAttachmentErrorTitleHtml"), messageBuffer.ToString(), false); } return true; }
/// <summary> /// Allow the application to modify the RenderContext before content is rendered. /// </summary> /// <param name="context">The context to render. Note: If app needs to change context.Script, /// it should do so by adding to the scriptBlock buffer. </param> /// <param name="scriptBlock">The script that will be written in the onLoad handler of LRM content. /// If this value is null, then the app /// cannot modify the onload script. (This happens when the resource being rendered is not /// the primary resource of an activity that is in LRM format.)</param> /// <param name="session">The session in which content is being rendered.</param> public void UpdateRenderContext(RenderContext context, StringBuilder scriptBlock, LearningSession session) { // Set values other than Response and RelativePath context.EmbeddedUIResourcePath = new Uri(Request.Url, "Images/"); // Set values that map to file extensions SetMappings(context.MimeTypeMapping, context.IisCompatibilityModeExtensions); if (scriptBlock == null) // This is not the primary resource, so nothing else matters return; // Basic Web Player never shows correct answers or reviewer info context.ShowCorrectAnswers = false; context.ShowReviewerInformation = false; }
internal RloDataModelContext(LearningSession session) { m_session = session; }
/// <summary> /// Create a context to send to an RloHandler when calling <c>RloHandler.Render</c>. /// </summary> /// <param name="session">The session that is being rendered.</param> /// <param name="renderContext">Information required to render the current file. /// </param> internal RloRenderContext(LearningSession session, RenderContext renderContext) : base(session) { m_context = renderContext; }
private LearningDataModel m_learningDataModel; // only used if m_session is null /// <summary> /// Create a context to send to an RloHandler. /// </summary> /// <param name="session">The session that is being rendered.</param> internal RloProcessFormDataContext(LearningSession session) { m_session = session; }
internal RloReactivateContext(LearningSession session, ReactivateSettings settings) : base(session) { m_resetPoints = ((settings & ReactivateSettings.ResetEvaluationPoints) != 0); m_resetComments = ((settings & ReactivateSettings.ResetEvaluationComments) != 0); }