Beispiel #1
0
        /// <summary>
        /// Get the attempt id requested for this session. This includes reading the LearnerAssignmentId parameter.
        /// </summary>
        /// <returns>Returns true if the attemptId is found. This method does not verify that the attemptId
        /// exists in LearningStore and does not create an attempt if the value is invalid.</returns>
        public virtual bool TryGetAttemptId(bool showErrorPage, out AttemptItemIdentifier attemptId)
        {
            // If there is an attempt id parameter, get it and return it. Don't ever show an error that AttemptId
            // was not provided. (The error will be that LearnerAssignmentId was not provided.)
            if (ProcessAttemptIdParameter(false, out attemptId))
            {
                return(true);
            }

            // If there's a LearnerAssignmentId, then you can use this to get the AttemptId, however it
            // causes a database call. Not good for routine page rendering (but ok the first time a frame
            // is shown).
            Guid learnerAssignmentGuidId;

            if (TryProcessLearnerAssignmentIdParameter(showErrorPage, out learnerAssignmentGuidId))
            {
                ClearError();

                // There was a learnerAssignmentId and no AttemptId, so translate from learnerAssignmentId to attemptId
                LearnerAssignmentGuidId = learnerAssignmentGuidId;
                LearnerAssignmentProperties la = GetLearnerAssignment();  // this causes LearningStoreAccess
                attemptId = la.AttemptId;
                return(attemptId != null);
            }
            return(false);
        }
        /// <summary>
        /// Send the non-elearning content to the response. Non-elearning content is any content other than
        /// scorm or lrm content. It is an error to call this method when the current learner assignment is elearning content.
        /// In some cases, this method will end the response.
        /// </summary>
        private void SendNonElearningContent()
        {
            // Get the cached learner assignment properties
            LearnerAssignmentProperties la = GetLearnerAssignment();

            SharePointFileLocation spFileLocation;

            if (!SharePointFileLocation.TryParse(la.Assignment.Location, out spFileLocation))
            {
                // location was not valid
                RegisterError(SlkFrameset.FRM_DocumentNotFoundTitleHtml, SlkFrameset.FRM_DocumentNotFound, false);
                return;
            }

            // Find the location of the document in the Sharepoint Document Library and go there
            string documentUrl = GetNonElearningDocumentUrl(spFileLocation);

            // Special case handling for HTML files:
            //   * Launch directly from the document library, not from the Cache
            //   * Add the LearnerAssignmentId to the Query portion of the URL so that we pass the learning context down to the content
            // This enables us to have more advanced behavior (CMI Tracking, scoring, completion status) for "Non-ELearning" documents.
            // It is a first step towards a more comprehensive strategy for adding educational workflow to all types of documents.
            if (documentUrl.EndsWith("html", StringComparison.OrdinalIgnoreCase) || documentUrl.EndsWith("htm", StringComparison.OrdinalIgnoreCase))
            {
                string redirectUrl = String.Format("{0}?{1}={2}", documentUrl, FramesetQueryParameter.LearnerAssignmentId, LearnerAssignmentGuidId.ToString());
                Response.Clear();
                Response.Redirect(redirectUrl, true); // ends response
            }

            string framesetPath = GetFramesetPath();

            Response.Clear();

            using (CachedSharePointFile cachedFile = new CachedSharePointFile(SlkStore.SharePointCacheSettings, spFileLocation, true))
            {
                // If the current request URL does not include the file name of the file, then this request is the first frameset rendering.
                // That means this will redirect to a URL that does include the filename of the file. This redirection allows the browser to
                // properly handle the content.
                if (String.IsNullOrEmpty(framesetPath))
                {
                    string redirectUrl = GetNonElearningFrameUrl(cachedFile.FileName);
                    cachedFile.Dispose();
                    Response.Redirect(redirectUrl, true);   // ends response
                }

                // This is the first actual access of the file. If it doesn't exist, the exception will be caught by the Page_load method.
                SetMimeType(cachedFile.FileName);

                // If this file is using IIS Compability mode, then we get the stream from the cached file and write it to the
                // response, otherwise, use TransmitFile.
                if (UseCompatibilityMode(cachedFile.FileName))
                {
                    WriteIisCompatibilityModeToResponse(cachedFile.GetFileStream());
                }
                else
                {
                    cachedFile.TransmitFile(Response);
                }
            }
        }
        public PlainTextString GetSessionTitle(LearningSession session)
        {
            FramesetUtil.ValidateNonNullParameter("session", session);

            LearnerAssignmentProperties la = GetLearnerAssignment();

            switch (session.View)
            {
            case SessionView.Execute:
                return(new PlainTextString(la.Assignment.Title));

            case SessionView.RandomAccess:
                return(new PlainTextString(ResHelper.Format("{0}: {1}", la.LearnerName, la.Assignment.Title)));

            case SessionView.Review:
            {
                if (IsInstructorReview)
                {
                    return(new PlainTextString(ResHelper.Format("{0}: {1}", la.LearnerName, la.Assignment.Title)));
                }
                else
                {
                    return(new PlainTextString(la.Assignment.Title));
                }
            }

            default:
                return(new PlainTextString(la.Assignment.Title));
            }
        }
Beispiel #4
0
        protected void slkButtonSubmit_Click(object sender, EventArgs e)
        {
            try
            {
                try
                {
                    LearnerAssignmentProperties.Submit();
                    LearnerAssignmentProperties.SaveLearnerComment(LearnerComments.Text);
                }
                catch (InvalidOperationException)
                {
                    // state transition isn't supported
                    errorBanner.AddException(SlkStore, new SafeToDisplayException(PageCulture.Resources.LobbyCannotChangeState));
                }

                // Clear the object so it will refresh from the database
                LearnerAssignmentProperties = null;
            }
            catch (LearningStoreConstraintViolationException exception)
            {
                // any exceptions here will be handled in PreRender
                errorBanner.AddException(SlkStore, new SafeToDisplayException(PageCulture.Resources.LobbySubmitException));
                SlkStore.LogException(exception);
            }
        }
Beispiel #5
0
        /// <summary>Process a request for a view. If not allowed, register an error and return false.</summary>
        public bool ProcessViewRequest(SessionView view, LearningSession session)
        {
            LearnerAssignmentProperties la = GetLearnerAssignment();

            LearnerAssignmentState state = la.Status == null ? LearnerAssignmentState.NotStarted : la.Status.Value;

            return(ProcessViewRequest(state, view));
        }
Beispiel #6
0
        /// <summary>The OK button event handler.</summary>
        protected void btnOK_Click(object sender, EventArgs e)
        {
            List <AssignmentUpload> uploadedFiles = FindUploadedFiles();

            if (uploadedFiles.Count > 0 || includes.Count > 0)
            {
                try
                {
                    List <int> filesToKeep = new List <int>();
                    foreach (CheckBox check in includes)
                    {
                        if (check.Checked)
                        {
                            if (check.ID.Length > 5)
                            {
                                int fileId = int.Parse(check.ID.Substring(5), CultureInfo.InvariantCulture);
                                filesToKeep.Add(fileId);
                            }
                        }
                    }

                    LearnerAssignmentProperties.UploadFilesAndSubmit(uploadedFiles.ToArray(), filesToKeep.ToArray());
                    LearnerAssignmentProperties.SaveLearnerComment(LearnerComments.Text);

                    //Redirect to the SLk ALWP Page
                    string redirectUrl = GenerateRedirectUrl();

                    HttpContext.Current.Response.Write(
                        "<script>var x = '" + PageCulture.Resources.FilesUploadPageSuccessMsg + "';" +
                        "var url = '" + redirectUrl + "';" +
                        "if (x != ''){alert(x);window.location=url;};</script>");
                }
                catch (SafeToDisplayException exception)
                {
                    contentPanel.Visible = false;
                    errorBanner.Clear();
                    errorBanner.AddError(ErrorType.Error, exception.Message);
                    errorBanner.Visible = true;
                }
                catch (Exception exception)
                {
                    contentPanel.Visible = false;
                    errorBanner.Clear();
                    errorBanner.AddError(ErrorType.Error, exception.ToString());
                    errorBanner.Visible = true;
                }
            }
            else
            {
                errorBanner.Clear();
                errorBanner.AddError(ErrorType.Info, PageCulture.Resources.FilesUploadOrCancel);
                errorBanner.Visible = true;
            }
        }
Beispiel #7
0
        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] // catch general exception so that message can be SLK-specific
        public bool TryGetAttemptInfo(bool showErrorPage, out AttemptItemIdentifier attemptId)
        {
            // Initialize out parameter
            attemptId = null;

            Guid learnerAssignmentKey;
            bool isValid = false;

            // For views based on an attempt, LearnerAssignmentId is required
            // It must be a positive long value.
            if (m_contentPathParts.Length >= 3)
            {
                learnerAssignmentKey = new Guid(m_contentPathParts[2]);
                if (learnerAssignmentKey != null)
                {
                    LearnerAssignmentGuidId = learnerAssignmentKey;
                }
            }

            try
            {
                learnerAssignment = GetLearnerAssignment();
                attemptId         = learnerAssignment.AttemptId;
                isValid           = true;
            }
            catch (HttpException)
            {
                // If something just happened with the connection, don't set header info
            }
            catch
            {
                // If we could not get the assignment, send the proper error codes
                Response.StatusCode        = 404;
                Response.StatusDescription = "Not Found";
            }

            if (!isValid)
            {
                if (showErrorPage)
                {
                    RegisterError(ResHelper.GetMessage(FramesetResources.CON_ContentCannotBeDisplayedTitle),
                                  ResHelper.GetMessage(FramesetResources.CON_ContentCannotBeDisplayedMsg), false);
                }
                return(false);
            }

            return(true);
        }
        void LoadAssignmentProperties()
        {
            if (SlkStore.IsInstructor(SPWeb))
            {
                this.assignmentProperties = SlkStore.LoadAssignmentPropertiesForLearner(LearnerAssignmentGuid, SlkRole.Instructor);
            }
            else if (SlkStore.IsLearner(SPWeb))
            {
                this.assignmentProperties = SlkStore.LoadAssignmentPropertiesForLearner(LearnerAssignmentGuid, SlkRole.Learner);
            }
            else if (SlkStore.IsObserver(SPWeb))
            {
               this.assignmentProperties = SlkStore.LoadAssignmentPropertiesForLearner(LearnerAssignmentGuid, SlkRole.Learner);
            }
            else
            {
                this.assignmentProperties = SlkStore.LoadAssignmentPropertiesForLearner(LearnerAssignmentGuid, SlkRole.None);
            }

            learnerAssignmentProperties = assignmentProperties.Results[0];
        }
Beispiel #9
0
        /// <summary>
        /// Provides an option to override and update the cached data about the
        /// current learner assignment.
        /// </summary>
        /// <param name="forceUpdate">If false, the value is cached.</param>
        /// <returns></returns>
        protected LearnerAssignmentProperties GetLearnerAssignment(bool forceUpdate)
        {
            // If the current value has not been set, or if we have to update it, get
            // the information from the base class.
            if (learnerAssignmentProperties == null || forceUpdate)
            {
                SlkRole slkRole;
                if (SlkStore.IsObserver(SPWeb) && AssignmentView == AssignmentView.StudentReview)
                {
                    // If the user is an observer and the AssignmentView is 'StudentReview', then
                    // set the slkrole to 'Observer'; Otherwise get the role using GetSlkRole method
                    slkRole = SlkRole.Observer;
                }
                else
                {
                    slkRole = GetSlkRole(AssignmentView);
                }

                AssignmentProperties assignment = SlkStore.LoadAssignmentPropertiesForLearner(LearnerAssignmentGuidId, slkRole);
                learnerAssignmentProperties = assignment.Results[0];
            }

            return(learnerAssignmentProperties);
        }
Beispiel #10
0
        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] // all exceptions caught and written to event log rather than getting aspx error page
        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                bool isPosted = false;
                if (String.CompareOrdinal(Request.HttpMethod, "POST") == 0)
                {
                    isPosted = true;
                }

                // Get the path to the content. This may be part of the url (if we are running without
                // an http module) or a URL parameter (with http module). We run in both modes because
                // VS.NET does not parse URLs of the form: /.../Content.aspx/0/1/foo.gif correctly without
                // the assistance of the module.
                m_contentPath = GetContentPath();

                SPSecurity.CatchAccessDeniedException = true;

                SlkUtilities.RetryOnDeadlock(delegate()
                {
                    // Initialize data that may get set on a first try, but must be reset for retry
                    Response.Clear();
                    ClearError();
                    learnerAssignment = null;

                    m_contentHelper = new ContentHelper(Request, Response, SlkEmbeddedUIPath);
                    m_contentHelper.ProcessPageLoad(SlkStore.PackageStore,
                                                    String.IsNullOrEmpty(m_contentPath),
                                                    isPosted,
                                                    TryGetViewInfo,
                                                    TryGetAttemptInfo,
                                                    TryGetActivityInfo,
                                                    GetResourcePath,
                                                    AppendContentFrameDetails,
                                                    UpdateRenderContext,
                                                    ProcessPostedData,
                                                    ProcessViewRequest,
                                                    ProcessPostedDataComplete,
                                                    RegisterError,
                                                    GetErrorInfo,
                                                    GetMessage);
                });
            }
            catch (ThreadAbortException)
            {
                // response ended. Do nothing.
                return;
            }
            catch (UnauthorizedAccessException uae)
            {
                SlkStore.LogError(FramesetResources.FRM_UnknownExceptionMsg, uae.ToString());
                RegisterError(ResHelper.GetMessage(FramesetResources.FRM_UnknownExceptionTitle),
                              ResHelper.GetMessage(SlkFrameset.FRM_UnexpectedExceptionMsg), false);

                // Clear the response in case something has been written
                Response.Clear();
            }
            catch (Exception e2)
            {
                // Unexpected exceptions are not shown to user
                SlkStore.LogError(FramesetResources.FRM_UnknownExceptionMsg, e2.ToString());
                RegisterError(ResHelper.GetMessage(FramesetResources.FRM_UnknownExceptionTitle),
                              ResHelper.GetMessage(SlkFrameset.FRM_UnexpectedExceptionMsg), false);

                // Clear the response in case something has been written
                Response.Clear();
            }
        }
Beispiel #11
0
        public void UpdateRenderContext(RenderContext context, StringBuilder scriptBlock, LearningSession session)
        {
            // Set values other than OutputStream and RelativePath
            context.EmbeddedUIResourcePath = new Uri(SlkEmbeddedUIPath, "Images/");

            SetMimeTypeMapping(context.MimeTypeMapping);

            SetIisCompatibilityModeExtensions(context.IisCompatibilityModeExtensions);

            // If this is not the primary resource, nothing else matters.
            if (scriptBlock == null)
            {
                return;
            }

            LearnerAssignmentProperties la = GetLearnerAssignment();

            switch (AssignmentView)
            {
            case AssignmentView.Execute:
            {
                context.ShowCorrectAnswers      = false;
                context.ShowReviewerInformation = false;
            }
            break;

            case AssignmentView.StudentReview:
            {
                context.ShowCorrectAnswers      = la.Assignment.ShowAnswersToLearners;
                context.ShowReviewerInformation = false;
            }
            break;

            case AssignmentView.InstructorReview:
            {
                context.ShowCorrectAnswers      = true;
                context.ShowReviewerInformation = true;
            }
            break;

            case AssignmentView.Grading:
            {
                context.ShowCorrectAnswers      = true;
                context.ShowReviewerInformation = true;
            }
            break;
            }

            // Update hidden controls and script to include assignment information if there is script
            // information to be written. Only write script in LRM content.
            if ((scriptBlock != null) && (session.CurrentActivityResourceType == ResourceType.Lrm))
            {
                WriteSlkMgrInit(scriptBlock);

                scriptBlock.AppendLine("slkMgr = Slk_GetSlkManager();");
                context.FormHiddenControls.Add(HiddenFieldNames.LearnerAssignmentId, FramesetUtil.GetStringInvariant(la.LearnerAssignmentId.GetKey()));
                scriptBlock.AppendFormat("slkMgr.LearnerAssignmentId = document.getElementById({0}).value;\r\n",
                                         JScriptString.QuoteString(HiddenFieldNames.LearnerAssignmentId, false));

                context.FormHiddenControls.Add(HiddenFieldNames.LearnerAssignmentStatus, SlkUtilities.GetLearnerAssignmentState(la.Status));
                scriptBlock.AppendFormat("slkMgr.Status = document.getElementById({0}).value;\r\n",
                                         JScriptString.QuoteString(HiddenFieldNames.LearnerAssignmentStatus, false));

                // Set the change in final points. This can only happen in grading.
                if (AssignmentView == AssignmentView.Grading)
                {
                    string finalPointsValue = "null";
                    float? finalPoints      = la.FinalPoints;
                    if (finalPoints != null)
                    {
                        // FinalPoints is invariant culture
                        finalPointsValue = Convert.ToString(finalPoints.Value, CultureInfo.InvariantCulture.NumberFormat);
                    }
                    scriptBlock.AppendFormat("slkMgr.FinalPoints = {0};\r\n", finalPointsValue);
                }

                // Send information about total points (ie, computed points on the client).
                if (session != null)
                {
                    if (session.TotalPoints != null)
                    {
                        // TotalPoints is passed in current culture, as a string
                        JScriptString totalPointsValue = JScriptString.QuoteString(Convert.ToString(session.TotalPoints, CultureInfo.CurrentCulture.NumberFormat), false);
                        scriptBlock.AppendFormat("slkMgr.ComputedPoints = {0};\r\n", totalPointsValue);
                    }
                    else
                    {
                        scriptBlock.Append("slkMgr.ComputedPoints = \"\";\r\n");
                    }


                    if (session.SuccessStatus != SuccessStatus.Unknown)
                    {
                        scriptBlock.AppendFormat("slkMgr.PassFail = {0};\r\n",
                                                 JScriptString.QuoteString(((session.SuccessStatus == SuccessStatus.Passed) ? "passed" : "failed"), false));
                    }
                }
            }
        }
Beispiel #12
0
 private void LoadAssignmentObjects()
 {
     assignmentProperties        = SlkStore.LoadAssignmentPropertiesForLearner(LearnerAssignmentGuidId, SlkRole.Learner);
     learnerAssignmentProperties = assignmentProperties.Results[0];
 }
Beispiel #13
0
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            try
            {
                // setting default title
                pageTitle.Text            = PageCulture.Resources.LobbyBeginAssignmentText;
                pageTitleInTitlePage.Text = PageCulture.Resources.LobbyBeginAssignmentText;

                SetResourceText();

                LearnerAssignmentState learnerAssignmentStatus = LearnerAssignmentProperties.Status.Value;
                startAssignment = (Request.QueryString[startQueryStringName] == "true");

                if (AssignmentProperties.IsNonELearning)
                {
                    HandleNonELearningAssignment();
                }

                if (startAssignment && learnerAssignmentStatus == LearnerAssignmentState.NotStarted)
                {
                    LearnerAssignmentProperties.Start();
                    learnerAssignmentStatus = LearnerAssignmentProperties.Status.Value;
                }

                ClientScript.RegisterClientScriptBlock(this.GetType(), "lblStatusValue", "var lblStatusValue = \"" + lblStatusValue.ClientID + "\";", true);

                StringBuilder clientScript        = new StringBuilder();
                string        submittedJavascript = string.Format("slkSubmittedUrl = '{0}{1}SubmittedFiles.aspx?LearnerAssignmentId=';", SPWeb.Url, Constants.SlkUrlPath);
                clientScript.AppendLine(submittedJavascript);

                string sourceUrl = string.Format("slkSourceUrl = '&source={0}';", HttpUtility.UrlEncode(Page.Request.RawUrl));
                clientScript.AppendLine(sourceUrl);

                ClientScript.RegisterClientScriptBlock(this.GetType(), "openSubmittedFiles", clientScript.ToString(), true);

                if (learnerAssignmentStatus == LearnerAssignmentState.Completed && AssignmentProperties.AutoReturn == true)
                {
                    // assignment was probably changed to be "auto-return" after this learner submitted it; we'll
                    // re-submit now to invoke the auto-return mechanism; note that we use
                    // LearnerAssignmentState.Completed instead of LearnerAssignmentState.Final because
                    // the latter would throw a security-related exception (learner's aren't allowed to move their
                    // learner assignments into Final state) -- using Completed works because
                    // SlkStore.ChangeLearnerAssignmentState performs auto-return even if the current state is
                    // LearnerAssignmentState.Completed
                    LearnerAssignmentProperties.Submit();
                    // Set the property to null so that it will refresh the next time it is referenced
                    LearnerAssignmentProperties = null;
                }

                SetUpDisplayValues(learnerAssignmentStatus);
                SetUpForAssignmentState(learnerAssignmentStatus);

                tgrAutoReturn.Visible = AssignmentProperties.AutoReturn;
                contentPanel.Visible  = true;
            }
            catch (InvalidOperationException ex)
            {
                SlkStore.LogException(ex);
                errorBanner.AddException(SlkStore, new SafeToDisplayException(PageCulture.Resources.LobbyInvalidLearnerAssignmentId, LearnerAssignmentGuidId.ToString()));
                contentPanel.Visible = false;
            }
            catch (ThreadAbortException)
            {
                // Calling Response.Redirect throws a ThreadAbortException which needs to be rethrown
                throw;
            }
            catch (Exception exception)
            {
                errorBanner.AddException(SlkStore, exception);
                contentPanel.Visible = false;
            }
        }
Beispiel #14
0
        /// <summary>Gets an appropriate message.</summary>
        /// <param name="stringId">The id of the message.</param>
        /// <returns>The message.</returns>
        public string GetMessage(FramesetStringId stringId)
        {
            switch (stringId)
            {
            case FramesetStringId.MoveToNextFailedHtml:
                return(SlkFrameset.HID_MoveNextFailedHtml);

            case FramesetStringId.MoveToPreviousFailedHtml:
                return(SlkFrameset.HID_MovePreviousFailedHtml);

            case FramesetStringId.MoveToActivityFailedHtml:
                return(SlkFrameset.HID_MoveToActivityFailedHtml);

            case FramesetStringId.SubmitPageTitleHtml:
                if (AssignmentView == AssignmentView.Execute)
                {
                    return(SlkFrameset.HID_SubmitPageTitleHtml);
                }
                else
                {
                    return(SlkFrameset.HID_SubmitGradingPageTitleHtml);
                }

            case FramesetStringId.SubmitPageMessageHtml:
                if (AssignmentView == AssignmentView.Execute)
                {
                    LearnerAssignmentProperties la = GetLearnerAssignment();
                    if (la.Assignment.IsSelfAssignment)
                    {
                        return(SlkFrameset.HID_SubmitPageMessageHtmlSelfAssignment);
                    }
                    else
                    {
                        return(SlkFrameset.HID_SubmitPageMessageHtml);
                    }
                }
                else
                {
                    return(SlkFrameset.HID_SubmitGradingPageMessageHtml);
                }

            case FramesetStringId.SubmitPageMessageNoCurrentActivityHtml:
                // This should not happen in grading view
                return(SlkFrameset.HID_SubmitPageMessageNoCurrentActivityHtml);

            case FramesetStringId.SubmitPageSaveButtonHtml:
                if (AssignmentView == AssignmentView.Execute)
                {
                    return(SlkFrameset.FRM_SubmitPageBtnHtml);
                }
                else
                {
                    return(SlkFrameset.FRM_SubmitGradingPageBtnHtml);
                }

            case FramesetStringId.CannotDisplayContentTitle:
                return(SlkFrameset.FRM_CannotDisplayContentTitle);

            case FramesetStringId.SessionIsNotActiveMsg:
                return(SlkFrameset.FRM_SessionIsNotActiveMsg);

            case FramesetStringId.SelectActivityTitleHtml:
                return(SlkFrameset.HID_SelectActivityTitleHtml);

            case FramesetStringId.SelectActivityMessageHtml:
                return(SlkFrameset.HID_SelectActivityMessageHtml);

            case FramesetStringId.ActivityIsNotActiveMsg:
                return(FramesetResources.FRM_ActivityIsNotActiveMsg);

            default:
                throw new InternalErrorException(SlkFrameset.FRM_ResourceNotFound);
            }
        }
        /// <summary>
        /// Saves the info from the grading list
        /// </summary>
        /// <param name="action">Determines how the learner assignment statud should be handled.</param>
        private void SaveGradingList(SaveAction action)
        {
            // gradingList.DeterminePostBackGradingItems() only returns the rows that have changed
            Dictionary <string, GradingItem>   gradingListItems      = gradingList.DeterminePostBackGradingItems();
            List <LearnerAssignmentProperties> gradingPropertiesList = new List <LearnerAssignmentProperties>();

            if (action == SaveAction.CollectAll || action == SaveAction.ReturnAll)
            {
                foreach (GradingItem item in gradingList.Items.Values)
                {
                    switch (action)
                    {
                    case SaveAction.CollectAll:
                        if (item.Status == LearnerAssignmentState.NotStarted || item.Status == LearnerAssignmentState.Active)
                        {
                            gradingListItems[item.LearnerAssignmentId.ToString(CultureInfo.InvariantCulture)] = item;
                        }
                        break;

                    case SaveAction.ReturnAll:
                        if (item.Status != LearnerAssignmentState.Final)
                        {
                            gradingListItems[item.LearnerAssignmentId.ToString(CultureInfo.InvariantCulture)] = item;
                        }
                        break;
                    }
                }
            }

            if (gradingListItems.Count > 0)
            {
                using (AssignmentSaver saver = AssignmentProperties.CreateSaver())
                {
                    bool hasSaved = false;
                    try
                    {
                        foreach (GradingItem item in gradingListItems.Values)
                        {
                            bool moveStatusForward = false;
                            bool returnAssignment  = false;
                            LearnerAssignmentProperties gradingProperties = AssignmentProperties[item.LearnerAssignmentId];
                            gradingProperties.FinalPoints        = item.FinalScore;
                            gradingProperties.Grade              = item.Grade;
                            gradingProperties.InstructorComments = item.InstructorComments;

                            // Ignore the FinalScore Update if the Status is NotStarted or Active
                            if (item.Status == LearnerAssignmentState.NotStarted || item.Status == LearnerAssignmentState.Active)
                            {
                                gradingProperties.IgnoreFinalPoints = true;
                            }

                            switch (action)
                            {
                            case SaveAction.SaveOnly:
                                // The Save or OK button was clicked
                                moveStatusForward = item.ActionState;
                                break;

                            case SaveAction.CollectAll:
                                // The Collect All button was clicked
                                if (item.Status == LearnerAssignmentState.NotStarted || item.Status == LearnerAssignmentState.Active)
                                {
                                    moveStatusForward = true;
                                }
                                break;

                            case SaveAction.ReturnAll:
                                if (item.Status != LearnerAssignmentState.Final)
                                {
                                    returnAssignment = true;
                                }
                                break;
                            }

                            gradingProperties.Save(moveStatusForward, returnAssignment, saver);
                        }

                        hasSaved = true;
                        saver.Save();
                    }
                    catch
                    {
                        if (hasSaved == false)
                        {
                            saver.Cancel();
                        }

                        throw;
                    }
                }
            }
        }
        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] // exceptions caught, added to event log
        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                SlkUtilities.RetryOnDeadlock(delegate()
                {
                    //Initialize data that may need to be reset on retry
                    Response.Clear();
                    ClearError();

                    m_sessionEnded = false;
                    m_hiddenHelper = new HiddenHelper(Request, Response, SlkEmbeddedUIPath);
                    m_hiddenHelper.ProcessPageLoad(SlkStore.PackageStore, GetSessionTitle, TryGetSessionView,
                                                   TryGetAttemptId, AppendContentFrameDetails, RegisterError,
                                                   GetErrorInfo, ProcessSessionEnd, ProcessViewRequest, GetMessage, IsPostBack);


                    // Send assignment information to client. If the session has ended, then force a reload of the current
                    // assignment properties. Otherwise, the cached value will have required info so no need to re-query database.
                    LearnerAssignmentProperties la = GetLearnerAssignment(SessionEnded);

                    // Add assignment information to the hidden controls
                    HiddenControlInfo hiddenCtrlInfo = new HiddenControlInfo();
                    hiddenCtrlInfo.Id    = new PlainTextString(HiddenFieldNames.LearnerAssignmentId);
                    hiddenCtrlInfo.Value = new PlainTextString(FramesetUtil.GetStringInvariant(la.LearnerAssignmentId.GetKey()));
                    hiddenCtrlInfo.FrameManagerInitializationScript = new JScriptString(ResHelper.Format("slkMgr.LearnerAssignmentId = document.getElementById({0}).value;",
                                                                                                         JScriptString.QuoteString(HiddenFieldNames.LearnerAssignmentId, false)));

                    m_hiddenHelper.HiddenControls.Add(hiddenCtrlInfo);

                    // Learner assignment status ('not started', 'in progress', etc)
                    hiddenCtrlInfo       = new HiddenControlInfo();
                    hiddenCtrlInfo.Id    = new PlainTextString(HiddenFieldNames.LearnerAssignmentStatus);
                    hiddenCtrlInfo.Value = new PlainTextString(SlkUtilities.GetLearnerAssignmentState(la.Status));
                    hiddenCtrlInfo.FrameManagerInitializationScript = new JScriptString(ResHelper.Format("slkMgr.Status = document.getElementById({0}).value;",
                                                                                                         JScriptString.QuoteString(HiddenFieldNames.LearnerAssignmentStatus, false)));

                    m_hiddenHelper.HiddenControls.Add(hiddenCtrlInfo);

                    hiddenCtrlInfo = new HiddenControlInfo();
                    if (la.FinalPoints != null)
                    {
                        // finalPoints is passed in invariant culture, as a float
                        hiddenCtrlInfo.FrameManagerInitializationScript = new JScriptString(ResHelper.Format("slkMgr.FinalPoints = {0};",
                                                                                                             Convert.ToString(la.FinalPoints, CultureInfo.InvariantCulture.NumberFormat)));
                    }
                    else
                    {
                        hiddenCtrlInfo.FrameManagerInitializationScript = new JScriptString("slkMgr.FinalPoints = null;");
                    }
                    m_hiddenHelper.HiddenControls.Add(hiddenCtrlInfo);

                    // Send information about total points (ie, computed points on the client). This is called 'graded score' in
                    // grading page.
                    LearningSession session = m_hiddenHelper.Session;
                    if (session != null)
                    {
                        hiddenCtrlInfo = new HiddenControlInfo();
                        if (session.TotalPoints != null)
                        {
                            // TotalPoints is passed in current culture, as a string
                            JScriptString totalPointsValue = JScriptString.QuoteString(Convert.ToString(session.TotalPoints, CultureInfo.CurrentCulture.NumberFormat), false);
                            hiddenCtrlInfo.FrameManagerInitializationScript = new JScriptString(ResHelper.Format("slkMgr.ComputedPoints = {0};", totalPointsValue));
                        }
                        else
                        {
                            hiddenCtrlInfo.FrameManagerInitializationScript = new JScriptString("slkMgr.ComputedPoints = \"\";");
                        }
                        m_hiddenHelper.HiddenControls.Add(hiddenCtrlInfo);

                        if (session.SuccessStatus != SuccessStatus.Unknown)
                        {
                            hiddenCtrlInfo = new HiddenControlInfo();
                            hiddenCtrlInfo.FrameManagerInitializationScript = new JScriptString(ResHelper.Format("slkMgr.PassFail = {0};\r\n",
                                                                                                                 JScriptString.QuoteString(((session.SuccessStatus == SuccessStatus.Passed) ? "passed" : "failed"), false)));

                            m_hiddenHelper.HiddenControls.Add(hiddenCtrlInfo);
                        }
                    }
                });
            }
            catch (Exception ex)
            {
                ClearError();

                // Unexpected exceptions are not shown to user
                SlkStore.LogError(FramesetResources.FRM_UnknownExceptionMsg, ex.ToString());
                RegisterError(ResHelper.GetMessage(FramesetResources.FRM_UnknownExceptionTitle),
                              ResHelper.GetMessage(SlkFrameset.FRM_UnexpectedExceptionMsg), false);
            }
        }
         SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods")]   // parameter is validated
        public void ProcessSessionEnd(LearningSession session, ref string messageTitle, ref string message)
        {
            FramesetUtil.ValidateNonNullParameter("session", session);

            // If we have already been here, then there is nothing more to do.
            if (SessionEnded)
            {
                return;
            }

            LearnerAssignmentProperties la = GetLearnerAssignment();

            // 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 = SlkFrameset.HID_SessionAbandonedTitle;
                        message      = SlkFrameset.HID_ExecuteViewAbandonedSessionMsg;
                        SessionEnded = true;
                        break;

                    case AttemptStatus.Completed:
                        messageTitle = SlkFrameset.HID_SessionCompletedTitle;
                        message      = SlkFrameset.HID_ExecuteViewCompletedSessionMsg;
                        SessionEnded = true;
                        break;

                    case AttemptStatus.Suspended:
                        messageTitle = SlkFrameset.HID_SessionSuspendedTitle;
                        message      = SlkFrameset.HID_ExecuteViewSuspendedSessionMsg;
                        // Do not set SessionEnded -- the session being suspended does not warrant ending the learner assignment
                        break;
                    }
                }

                if (SessionEnded)
                {
                    // Call FinishLearnerAssignment since the attempt has already been completed.
                    SlkStore.FinishLearnerAssignment(LearnerAssignmentGuidId);
                }
            }
            else if (session.View == SessionView.RandomAccess)
            {
                messageTitle = SlkFrameset.HID_GradingFinishedTitle;
                message      = SlkFrameset.HID_GradingFinishedMessage;
                StringBuilder sb = new StringBuilder(1000);
                sb.Append(message);
                sb.Append("<br><script>");

                // Write the assignment status to slkFrameMgr
                WriteSlkMgrInit(sb);

                sb.AppendLine("slkMgr = Slk_GetSlkManager();");
                sb.AppendFormat("slkMgr.LearnerAssignmentId = {0};\r\n",
                                JScriptString.QuoteString(FramesetUtil.GetStringInvariant(la.LearnerAssignmentId.GetKey()), false));

                sb.AppendFormat("slkMgr.Status = {0};\r\n",
                                JScriptString.QuoteString(SlkUtilities.GetLearnerAssignmentState(la.Status), false));

                if (AssignmentView == AssignmentView.Grading)
                {
                    string finalPointsValue = "null";
                    float? finalPoints      = la.FinalPoints;
                    if (finalPoints != null)
                    {
                        finalPointsValue = Convert.ToString(finalPoints.Value, CultureInfo.InvariantCulture.NumberFormat);
                    }
                    sb.AppendFormat("slkMgr.FinalPoints = {0};\r\n", finalPointsValue);
                }

                // Send information about total points (ie, computed points on the client).
                if (session != null)
                {
                    if (session.TotalPoints != null)
                    {
                        sb.AppendFormat("slkMgr.ComputedPoints = {0};\r\n",
                                        JScriptString.QuoteString(Convert.ToString(session.TotalPoints, CultureInfo.CurrentCulture.NumberFormat), false));
                    }
                    else
                    {
                        sb.AppendFormat("slkMgr.ComputedPoints = \"\";\r\n");
                    }

                    if (session.SuccessStatus != SuccessStatus.Unknown)
                    {
                        sb.AppendFormat("slkMgr.PassFail = {0};\r\n",
                                        JScriptString.QuoteString(((session.SuccessStatus == SuccessStatus.Passed) ? "passed" : "failed"), false));
                    }
                }
            }
        }