/// <summary> /// Checks if related to topic package has been already uploaded. /// In case it was not uploaded - upload package. /// Check attempt has been created and get attempt id. /// </summary> /// <param name="curriculumChapterTopicId">Iudico CurriculumChapterTopic.Id</param> /// <param name="courseId">Iudico Course.Id</param> /// <param name="topicType"><see cref="TopicTypeEnum"/> enumeration value.</param> /// <returns>Long integer value representing attempt id.</returns> public long GetAttemptId(int curriculumChapterTopicId, int courseId, TopicTypeEnum topicType) { this.GetCurrentUserIdentifier(); AttemptItemIdentifier attemptId; ActivityPackageItemIdentifier organizationId; var packageId = this.GetPackageIdentifier(courseId); // in case package has not been uploaded yet. if (packageId == null) { string zipPath = this.CourseService.Export(courseId, true); Package package = new ZipPackage(zipPath); package.CourseID = courseId; packageId = this.AddPackage(package); organizationId = this.GetOrganizationIdentifier(packageId); attemptId = this.CreateAttempt(organizationId.GetKey(), curriculumChapterTopicId, topicType); } else { // otherwise check if attempt was created organizationId = this.GetOrganizationIdentifier(packageId); AttemptItemIdentifier attId = this.GetAttemptIdentifier( organizationId, curriculumChapterTopicId, topicType); attemptId = attId ?? this.CreateAttempt(organizationId.GetKey(), curriculumChapterTopicId, topicType); } return(attemptId.GetKey()); }
/// <summary> /// Retrieves attempt identifier for specified organization id and Iudico topic id. /// </summary> /// <param name="orgId"><c>ActivityPackageItemIdentifier</c> value representing Organization ID.</param> /// <param name="curriculumChapterTopicId">Integer value - IUDICO curriculum chapter topic id.</param> /// <param name="topicType"><see cref="TopicTypeEnum"/> value.</param> /// <returns><c>AttemptItemIdentifier</c> value representing Attempt Identifier.</returns> protected AttemptItemIdentifier GetAttemptIdentifier( ActivityPackageItemIdentifier orgId, int curriculumChapterTopicId, TopicTypeEnum topicType) { AttemptItemIdentifier result = null; LearningStoreJob job = this.LStore.CreateJob(); LearningStoreQuery query = this.LStore.CreateQuery(Schema.MyAttemptIds.ViewName); query.AddColumn(Schema.MyAttemptIds.AttemptId); query.SetParameter(Schema.MyAttemptIds.CurriculumChapterTopicId, curriculumChapterTopicId); query.SetParameter(Schema.MyAttemptIds.OrganizationId, orgId); query.SetParameter(Schema.MyAttemptIds.TopicType, topicType); job.PerformQuery(query); ReadOnlyCollection <object> resultList = job.Execute(); var dataTable = (DataTable)resultList[0]; if (dataTable.Rows.Count > 0) { // get last result LStoreHelper.Cast(dataTable.Rows[dataTable.Rows.Count - 1][Schema.MyAttemptIds.AttemptId], out result); } return(result); }
public bool GetAttemptInfo(bool showErrorPage, out AttemptItemIdentifier attemptId) { attemptId = null; long attemptKey; bool isValid = false; // For views based on an attempt, AttemptId is required // It must be a positive long value. if (m_contentPathParts.Length >= 3) { if (long.TryParse(m_contentPathParts[2], out attemptKey)) { if (attemptKey > 0) { attemptId = new AttemptItemIdentifier(attemptKey); isValid = true; } } } if (!isValid) { if (showErrorPage) { RegisterError(ResHelper.GetMessage(IUDICO.TestingSystem.Localization.getMessage("CON_ContentCannotBeDisplayedTitle")), ResHelper.GetMessage(IUDICO.TestingSystem.Localization.getMessage("CON_ContentCannotBeDisplayedMsg")), false); } return(false); } return(true); }
/// <summary> /// Converts a value returned from a LearningStore query to a /// <c>AttemptItemIdentifier</c>. Throws an exception if the value is <c>DBNull</c>. /// </summary> /// /// <param name="value">A value from a <c>DataRow</c> within a <c>DataTable</c> /// returned from a LearningStore query.</param> /// /// <param name="result">Where to store the result.</param> /// public static void CastNonNull(object value, out AttemptItemIdentifier result) { LearningStoreItemIdentifier id; CastNonNull(value, out id); result = new AttemptItemIdentifier(id); }
/// <summary> /// Converts a value returned from a LearningStore query to a <c>AttemptItemIdentifier</c>, /// or <c>null</c> if the value is <c>DBNull</c>. /// </summary> /// /// <param name="value">A value from a <c>DataRow</c> within a <c>DataTable</c> /// returned from a LearningStore query.</param> /// /// <param name="result">Where to store the result.</param> /// public static void Cast(object value, out AttemptItemIdentifier result) { LearningStoreItemIdentifier id; Cast(value, out id); result = (id == null) ? null : new AttemptItemIdentifier(id); }
/// <summary> /// Checks if related to topic package has been already uploaded. /// In case it was not uploaded - upload package. /// Check attempt has been created and get attempt id. /// </summary> /// <param name="topic">Topic object represents specified topic.</param> /// <returns>Long integer value representing attempt id.</returns> public long GetAttemptId(Topic topic) { GetCurrentUserIdentifier(); AttemptItemIdentifier attemptId = null; ActivityPackageItemIdentifier organizationId; var packageId = GetPackageIdentifier(topic.CourseRef.Value); // in case package has not been uploaded yet. if (packageId == null) { string zipPath = CourseService.Export(topic.CourseRef.Value); Package package = new ZipPackage(zipPath); package.CourseID = topic.CourseRef.Value; packageId = AddPackage(package); organizationId = GetOrganizationIdentifier(packageId); attemptId = CreateAttempt(organizationId.GetKey(), topic.Id); } // otherwise check if attempt was created else { organizationId = GetOrganizationIdentifier(packageId); AttemptItemIdentifier attId = GetAttemptIdentifier(organizationId, topic.Id); if (attId != null) { attemptId = attId; } else { attemptId = CreateAttempt(organizationId.GetKey(), topic.Id); } } return(attemptId.GetKey()); }
/// <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> /// Requests that the list of all answers by specified attempt on organization. /// Adds the request to a given <c>LearningStoreJob</c> for later execution. /// </summary> /// <param name="job">A <c>LearningStoreJob</c> to add the new query to.</param> /// <param name="attemptId"><c>AttemptItemIdentifier</c> represents id of attempt.</param> protected void RequestInteractionResultsByAttempt(LearningStoreJob job, AttemptItemIdentifier attemptId) { LearningStoreQuery query = this.LStore.CreateQuery(Schema.InteractionResultsByAttempt.ViewName); query.AddColumn(Schema.InteractionResultsByAttempt.ActivityAttemptId); query.AddColumn(Schema.InteractionResultsByAttempt.ActivityPackageId); query.AddColumn(Schema.InteractionResultsByAttempt.ActivityTitle); query.AddColumn(Schema.InteractionResultsByAttempt.InteractionId); query.AddColumn(Schema.InteractionResultsByAttempt.CompletionStatus); query.AddColumn(Schema.InteractionResultsByAttempt.SuccessStatus); query.AddColumn(Schema.InteractionResultsByAttempt.LearnerResponseBool); query.AddColumn(Schema.InteractionResultsByAttempt.LearnerResponseString); query.AddColumn(Schema.InteractionResultsByAttempt.LearnerResponseNumeric); query.AddColumn(Schema.InteractionResultsByAttempt.CorrectResponse); query.AddColumn(Schema.InteractionResultsByAttempt.InteractionType); query.AddColumn(Schema.InteractionResultsByAttempt.MinScore); query.AddColumn(Schema.InteractionResultsByAttempt.MaxScore); query.AddColumn(Schema.InteractionResultsByAttempt.RawScore); query.AddColumn(Schema.InteractionResultsByAttempt.ScaledScore); query.AddColumn(Schema.InteractionResultsByAttempt.PrimaryResourceFromManifest); query.SetParameter(Schema.InteractionResultsByAttempt.AttemptIdParam, attemptId); job.PerformQuery(query); }
[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); }
/// <summary> /// Deletes pacakge and related attempts from database. /// </summary> /// <param name="packId">Long integer value represents package identifier.</param> protected void DeletePackage(long packId) { // set <packageId> to the ID of this package PackageItemIdentifier packageId = new PackageItemIdentifier(packId); // before we delete the package, we need to delete all attempts on the package -- // the following query looks for those attempts LearningStoreJob job = LStore.CreateJob(); LearningStoreQuery query = LStore.CreateQuery( Schema.MyAttempts.ViewName); query.AddCondition(Schema.MyAttempts.PackageId, LearningStoreConditionOperator.Equal, packageId); query.AddCondition(Schema.MyAttempts.AttemptId, LearningStoreConditionOperator.NotEqual, null); query.AddColumn(Schema.MyAttempts.AttemptId); query.AddSort(Schema.MyAttempts.AttemptId, LearningStoreSortDirection.Ascending); job.PerformQuery(query); DataTable dataTable = job.Execute <DataTable>(); AttemptItemIdentifier previousAttemptId = null; // loop once for each attempt on this package foreach (DataRow dataRow in dataTable.Rows) { // set <attemptId> to the ID of this attempt AttemptItemIdentifier attemptId; LStoreHelper.CastNonNull(dataRow["AttemptId"], out attemptId); // if <attemptId> is a duplicate attempt ID, skip it; note that the query // results are sorted by attempt ID (see above) if ((previousAttemptId != null) && (previousAttemptId.GetKey() == attemptId.GetKey())) { continue; } // delete this attempt StoredLearningSession.DeleteAttempt(LStore, attemptId); // continue to the next attempt previousAttemptId = attemptId; } // delete the package PStore.DeletePackage(packageId); }
/// <summary> /// Helper function to get the AttemptId query parameter. This method assumes the parameter is required. If /// it does not exist or is not numeric, the error page is shown. This method does not check LearningStore. /// </summary> /// <param name="isRequired">If true, the error page is shown if the value is not provided.</param> /// <param name="attemptId">The attempt id.</param> /// <returns>If false, the value did not exist or was not valid. The application should not continue with /// page processing.</returns> public bool ProcessAttemptIdParameter(bool showErrorPage, out AttemptItemIdentifier attemptId) { string attemptParam = null; bool isValid = true; attemptId = null; if (!this.GetRequiredParameter(FramesetQueryParameter.AttemptId, out attemptParam)) { return(false); } // Try converting it to a long value. It must be positive. try { long attemptKey = long.Parse(attemptParam, NumberFormatInfo.InvariantInfo); if (attemptKey <= 0) { isValid = false; } else { attemptId = new AttemptItemIdentifier(attemptKey); } } catch (FormatException) { isValid = false; } if (!isValid && showErrorPage) { this.RegisterError( ResHelper.GetMessage(Localization.GetMessage("FRM_InvalidParameterTitle"), FramesetQueryParameter.AttemptId), ResHelper.GetMessage(Localization.GetMessage("FRM_InvalidParameterMsg"), FramesetQueryParameter.AttemptId, attemptParam), false); } return(isValid); }
/// <summary>Tries to get the attempt id.</summary> public override bool TryGetAttemptId(bool showErrorPage, out AttemptItemIdentifier attemptId) { string attemptIdParam = null; bool isValid = true; // make compiler happy attemptId = null; if (!TryGetRequiredParameter(FramesetQueryParameter.AttemptId, out attemptIdParam)) { return(false); } // Try converting it to a long value. It must be positive. try { long attemptIdKey = long.Parse(attemptIdParam, NumberFormatInfo.InvariantInfo); if (attemptIdKey <= 0) { isValid = false; } else { attemptId = new AttemptItemIdentifier(attemptIdKey); } } catch (FormatException) { isValid = false; } if (!isValid && showErrorPage) { RegisterError(ResHelper.GetMessage(FramesetResources.FRM_InvalidParameterTitle, FramesetQueryParameter.AttemptId), ResHelper.GetMessage(FramesetResources.FRM_InvalidParameterMsg, FramesetQueryParameter.AttemptId, attemptIdParam), false); } return(isValid); }
/// <summary> /// Retrieves attempt identifier for specified organization id and Iudico topic id. /// </summary> /// <param name="orgId"><c>ActivityPackageItemIdentifier</c> value representing Organization ID.</param> /// <param name="topicId">Integer value - IUDICO topic id.</param> /// <returns><c>AttemptItemIdentifier</c> value representing Attempt Identifier.</returns> protected AttemptItemIdentifier GetAttemptIdentifier(ActivityPackageItemIdentifier orgId, int topicId) { AttemptItemIdentifier result = null; LearningStoreJob job = LStore.CreateJob(); LearningStoreQuery query = LStore.CreateQuery(Schema.MyAttempts.ViewName); query.AddColumn(Schema.MyAttempts.AttemptId); query.AddCondition(Schema.MyAttempts.OrganizationId, LearningStoreConditionOperator.Equal, orgId); query.AddCondition(Schema.MyAttempts.ThemeId, LearningStoreConditionOperator.Equal, topicId); job.PerformQuery(query); ReadOnlyCollection <object> resultList = job.Execute(); DataTable dataTable = (DataTable)resultList[0]; if (dataTable.Rows.Count > 0) { // get last result LStoreHelper.Cast(dataTable.Rows[dataTable.Rows.Count - 1][Schema.MyAttempts.AttemptId], out result); } return(result); }
public IEnumerable <AnswerResult> GetAnswers(AttemptResult attemptResult) { LearningStoreJob job = this.LStore.CreateJob(); var attemptId = new AttemptItemIdentifier(attemptResult.AttemptId); this.RequestInteractionResultsByAttempt(job, attemptId); var dataTable = job.Execute <DataTable>(); foreach (DataRow dataRow in dataTable.AsEnumerable()) { ActivityAttemptItemIdentifier activityAttemptItemId; LStoreHelper.CastNonNull( dataRow[Schema.InteractionResultsByAttempt.ActivityAttemptId], out activityAttemptItemId); long activityAttemptId = activityAttemptItemId.GetKey(); ActivityPackageItemIdentifier activityPackageItemId; LStoreHelper.CastNonNull( dataRow[Schema.InteractionResultsByAttempt.ActivityPackageId], out activityPackageItemId); long activityPackageId = activityPackageItemId.GetKey(); string activityTitle; LStoreHelper.CastNonNull(dataRow[Schema.InteractionResultsByAttempt.ActivityTitle], out activityTitle); InteractionItemIdentifier interactionItemId; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.InteractionId], out interactionItemId); long?interactionId = null; if (interactionItemId != null) { interactionId = interactionItemId.GetKey(); } CompletionStatus completionStatus; LStoreHelper.CastNonNull( dataRow[Schema.InteractionResultsByAttempt.CompletionStatus], out completionStatus); var iudicoCompletionStatus = (Common.Models.Shared.Statistics.CompletionStatus)completionStatus; SuccessStatus?successStatus; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.SuccessStatus], out successStatus); var iudicoSuccessStatus = (Common.Models.Shared.Statistics.SuccessStatus?)successStatus; bool?learnerResponseBool; LStoreHelper.Cast( dataRow[Schema.InteractionResultsByAttempt.LearnerResponseBool], out learnerResponseBool); string learnerResponseString; LStoreHelper.Cast( dataRow[Schema.InteractionResultsByAttempt.LearnerResponseString], out learnerResponseString); double?learnerResponseNumeric; LStoreHelper.Cast( dataRow[Schema.InteractionResultsByAttempt.LearnerResponseNumeric], out learnerResponseNumeric); object learnerResponse = null; if (learnerResponseBool != null) { learnerResponse = learnerResponseBool; } if (learnerResponseString != null) { learnerResponse = learnerResponseString; } if (learnerResponseNumeric != null) { learnerResponse = learnerResponseNumeric; } string correctResponse; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.CorrectResponse], out correctResponse); InteractionType?interactionType; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.InteractionType], out interactionType); Common.Models.Shared.Statistics.InteractionType?learnerResponseType = null; if (interactionType != null) { learnerResponseType = (Common.Models.Shared.Statistics.InteractionType)interactionType; } float?minScore; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.MinScore], out minScore); float?maxScore; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.MaxScore], out maxScore); float?rawScore; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.RawScore], out rawScore); float?scaledScore; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.ScaledScore], out scaledScore); string primaryResourceFromManifest; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.PrimaryResourceFromManifest], out primaryResourceFromManifest); // Create AnswerResult object var answerResult = new AnswerResult( activityAttemptId, activityPackageId, activityTitle, interactionId, iudicoCompletionStatus, iudicoSuccessStatus, attemptResult, learnerResponse, correctResponse, learnerResponseType, minScore, maxScore, rawScore, scaledScore, primaryResourceFromManifest); yield return(answerResult); } }
public bool ProcessAttemptIdParameter(bool showErrorPage, out AttemptItemIdentifier attemptId) { return(FramesetHelper.TryProcessAttemptIdParameter(showErrorPage, out attemptId)); }
public IEnumerable<AnswerResult> GetAnswers(AttemptResult attemptResult) { List<AnswerResult> result = new List<AnswerResult>(); LearningStoreJob job = LStore.CreateJob(); AttemptItemIdentifier attemptId = new AttemptItemIdentifier(attemptResult.AttemptId); RequestInteractionResultsByAttempt(job, attemptId); DataTable dataTable = job.Execute<DataTable>(); foreach (DataRow dataRow in dataTable.AsEnumerable()) { ActivityAttemptItemIdentifier activityAttemptItemId; LStoreHelper.CastNonNull(dataRow[Schema.InteractionResultsByAttempt.ActivityAttemptId], out activityAttemptItemId); long activityAttemptId = activityAttemptItemId.GetKey(); ActivityPackageItemIdentifier activityPackageItemId; LStoreHelper.CastNonNull(dataRow[Schema.InteractionResultsByAttempt.ActivityPackageId], out activityPackageItemId); long activityPackageId = activityPackageItemId.GetKey(); String activityTitle; LStoreHelper.CastNonNull(dataRow[Schema.InteractionResultsByAttempt.ActivityTitle], out activityTitle); InteractionItemIdentifier interactionItemId; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.InteractionId], out interactionItemId); long? interactionId = null; if (interactionItemId != null) { interactionId = interactionItemId.GetKey(); } Microsoft.LearningComponents.CompletionStatus completionStatus; LStoreHelper.CastNonNull(dataRow[Schema.InteractionResultsByAttempt.CompletionStatus], out completionStatus); IUDICO.Common.Models.Shared.Statistics.CompletionStatus iudicoCompletionStatus = (IUDICO.Common.Models.Shared.Statistics.CompletionStatus)completionStatus; Microsoft.LearningComponents.SuccessStatus? successStatus; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.SuccessStatus], out successStatus); IUDICO.Common.Models.Shared.Statistics.SuccessStatus? iudicoSuccessStatus = (IUDICO.Common.Models.Shared.Statistics.SuccessStatus?)successStatus; bool? learnerResponseBool = null; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.LearnerResponseBool], out learnerResponseBool); string learnerResponseString = null; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.LearnerResponseString], out learnerResponseString); double? learnerResponseNumeric = null; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.LearnerResponseNumeric], out learnerResponseNumeric); object learnerResponse = null; if (learnerResponseBool != null) { learnerResponse = learnerResponseBool; } if (learnerResponseString != null) { learnerResponse = learnerResponseString; } if (learnerResponseNumeric != null) { learnerResponse = learnerResponseNumeric; } string correctResponse; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.CorrectResponse], out correctResponse); Microsoft.LearningComponents.InteractionType? interactionType = null; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.InteractionType], out interactionType); IUDICO.Common.Models.Shared.Statistics.InteractionType? learnerResponseType = null; if (interactionType != null) { learnerResponseType = (IUDICO.Common.Models.Shared.Statistics.InteractionType)interactionType; } float? scaledScore; LStoreHelper.Cast<float>(dataRow[Schema.InteractionResultsByAttempt.ScaledScore], out scaledScore); // Create AnswerResult object AnswerResult answerResult = new AnswerResult(activityAttemptId, activityPackageId, activityTitle, interactionId, iudicoCompletionStatus, iudicoSuccessStatus, attemptResult, learnerResponse, correctResponse, learnerResponseType, scaledScore); result.Add(answerResult); } return result; }
public IEnumerable <AnswerResult> GetAnswers(AttemptResult attemptResult) { List <AnswerResult> result = new List <AnswerResult>(); LearningStoreJob job = LStore.CreateJob(); AttemptItemIdentifier attemptId = new AttemptItemIdentifier(attemptResult.AttemptId); RequestInteractionResultsByAttempt(job, attemptId); DataTable dataTable = job.Execute <DataTable>(); foreach (DataRow dataRow in dataTable.AsEnumerable()) { ActivityAttemptItemIdentifier activityAttemptItemId; LStoreHelper.CastNonNull(dataRow[Schema.InteractionResultsByAttempt.ActivityAttemptId], out activityAttemptItemId); long activityAttemptId = activityAttemptItemId.GetKey(); ActivityPackageItemIdentifier activityPackageItemId; LStoreHelper.CastNonNull(dataRow[Schema.InteractionResultsByAttempt.ActivityPackageId], out activityPackageItemId); long activityPackageId = activityPackageItemId.GetKey(); String activityTitle; LStoreHelper.CastNonNull(dataRow[Schema.InteractionResultsByAttempt.ActivityTitle], out activityTitle); InteractionItemIdentifier interactionItemId; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.InteractionId], out interactionItemId); long?interactionId = null; if (interactionItemId != null) { interactionId = interactionItemId.GetKey(); } Microsoft.LearningComponents.CompletionStatus completionStatus; LStoreHelper.CastNonNull(dataRow[Schema.InteractionResultsByAttempt.CompletionStatus], out completionStatus); IUDICO.Common.Models.Shared.Statistics.CompletionStatus iudicoCompletionStatus = (IUDICO.Common.Models.Shared.Statistics.CompletionStatus)completionStatus; Microsoft.LearningComponents.SuccessStatus?successStatus; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.SuccessStatus], out successStatus); IUDICO.Common.Models.Shared.Statistics.SuccessStatus?iudicoSuccessStatus = (IUDICO.Common.Models.Shared.Statistics.SuccessStatus?)successStatus; bool?learnerResponseBool = null; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.LearnerResponseBool], out learnerResponseBool); string learnerResponseString = null; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.LearnerResponseString], out learnerResponseString); double?learnerResponseNumeric = null; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.LearnerResponseNumeric], out learnerResponseNumeric); object learnerResponse = null; if (learnerResponseBool != null) { learnerResponse = learnerResponseBool; } if (learnerResponseString != null) { learnerResponse = learnerResponseString; } if (learnerResponseNumeric != null) { learnerResponse = learnerResponseNumeric; } string correctResponse; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.CorrectResponse], out correctResponse); Microsoft.LearningComponents.InteractionType?interactionType = null; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.InteractionType], out interactionType); IUDICO.Common.Models.Shared.Statistics.InteractionType?learnerResponseType = null; if (interactionType != null) { learnerResponseType = (IUDICO.Common.Models.Shared.Statistics.InteractionType)interactionType; } float?scaledScore; LStoreHelper.Cast <float>(dataRow[Schema.InteractionResultsByAttempt.ScaledScore], out scaledScore); // Create AnswerResult object AnswerResult answerResult = new AnswerResult(activityAttemptId, activityPackageId, activityTitle, interactionId, iudicoCompletionStatus, iudicoSuccessStatus, attemptResult, learnerResponse, correctResponse, learnerResponseType, scaledScore); result.Add(answerResult); } return(result); }
/// <summary> /// Requests that the list of all answers by specified attempt on organization. /// Adds the request to a given <c>LearningStoreJob</c> for later execution. /// </summary> /// <param name="job">A <c>LearningStoreJob</c> to add the new query to.</param> /// <param name="attemptId"><c>AttemptItemIdentifier</c> represents id of attempt.</param> protected void RequestInteractionResultsByAttempt(LearningStoreJob job, AttemptItemIdentifier attemptId) { LearningStoreQuery query = LStore.CreateQuery(Schema.InteractionResultsByAttempt.ViewName); query.AddColumn(Schema.InteractionResultsByAttempt.ActivityAttemptId); query.AddColumn(Schema.InteractionResultsByAttempt.ActivityPackageId); query.AddColumn(Schema.InteractionResultsByAttempt.ActivityTitle); query.AddColumn(Schema.InteractionResultsByAttempt.InteractionId); query.AddColumn(Schema.InteractionResultsByAttempt.CompletionStatus); query.AddColumn(Schema.InteractionResultsByAttempt.SuccessStatus); query.AddColumn(Schema.InteractionResultsByAttempt.LearnerResponseBool); query.AddColumn(Schema.InteractionResultsByAttempt.LearnerResponseString); query.AddColumn(Schema.InteractionResultsByAttempt.LearnerResponseNumeric); query.AddColumn(Schema.InteractionResultsByAttempt.CorrectResponse); query.AddColumn(Schema.InteractionResultsByAttempt.InteractionType); query.AddColumn(Schema.InteractionResultsByAttempt.ScaledScore); query.SetParameter(Schema.InteractionResultsByAttempt.AttemptIdParam, attemptId); job.PerformQuery(query); }
public bool GetAttemptInfo(bool showErrorPage, out AttemptItemIdentifier attemptId) { attemptId = null; long attemptKey; bool isValid = false; // For views based on an attempt, AttemptId is required // It must be a positive long value. if (this.mContentPathParts.Length >= 3) { if (long.TryParse(this.mContentPathParts[2], out attemptKey)) { if (attemptKey > 0) { attemptId = new AttemptItemIdentifier(attemptKey); isValid = true; } } } if (!isValid) { if (showErrorPage) { this.RegisterError( ResHelper.GetMessage(Localization.GetMessage("CON_ContentCannotBeDisplayedTitle")), ResHelper.GetMessage(Localization.GetMessage("CON_ContentCannotBeDisplayedMsg")), false); } return false; } return true; }
protected void DeletePackagesButton_Click(object sender, EventArgs e) { // the user clicked "Upload"... // hide the confirmation panel ConfirmMessage.Visible = false; // the PackagesToDelete hidden form element contains a comma-delimited list of IDs of // packages to delete (copied from <dialogArguments> on the client) -- attempt to delete // those packages, and set <deleted> to the IDs of packages successfully deleted List <string> deleted = new List <string>(); try { // loop once for each package to delete foreach (string id in PackagesToDelete.Value.Split(',')) { // set <packageId> to the ID of this package PackageItemIdentifier packageId = new PackageItemIdentifier( Convert.ToInt64(id, CultureInfo.InvariantCulture)); // before we delete the package, we need to delete all attempts on the package -- // the following query looks for those attempts LearningStoreJob job = LStore.CreateJob(); LearningStoreQuery query = LStore.CreateQuery( Schema.MyAttemptsAndPackages.ViewName); query.AddCondition(Schema.MyAttemptsAndPackages.PackageId, LearningStoreConditionOperator.Equal, packageId); query.AddCondition(Schema.MyAttemptsAndPackages.AttemptId, LearningStoreConditionOperator.NotEqual, null); query.AddColumn(Schema.MyAttemptsAndPackages.AttemptId); query.AddSort(Schema.MyAttemptsAndPackages.AttemptId, LearningStoreSortDirection.Ascending); job.PerformQuery(query); DataTable dataTable = job.Execute <DataTable>(); AttemptItemIdentifier previousAttemptId = null; // loop once for each attempt on this package foreach (DataRow dataRow in dataTable.Rows) { // set <attemptId> to the ID of this attempt AttemptItemIdentifier attemptId; LStoreHelper.CastNonNull(dataRow["AttemptId"], out attemptId); // if <attemptId> is a duplicate attempt ID, skip it; note that the query // results are sorted by attempt ID (see above) if ((previousAttemptId != null) && (previousAttemptId.GetKey() == attemptId.GetKey())) { continue; } // delete this attempt StoredLearningSession.DeleteAttempt(LStore, attemptId); // continue to the next attempt previousAttemptId = attemptId; } // delete the package PStore.DeletePackage(packageId); // add the package ID to the list of deleted packages deleted.Add(id); } // the operation was successful, and there are no messages to // display to the user, so close the dialog CloseDialogScript.Visible = true; } catch (Exception ex) { // an unexpected error occurred -- display a generic message that // doesn't include the exception message (since that message may // include sensitive information), and write the exception message // to the event log ErrorIntro.Visible = true; ErrorMessage.Visible = true; ErrorMessage.Controls.Add(new System.Web.UI.LiteralControl( Server.HtmlEncode("A serious error occurred. Please contact your system administrator. More information has been written to the server event log."))); LogEvent(System.Diagnostics.EventLogEntryType.Error, "An exception occurred while deleting a package:\n\n{0}\n\n", ex.ToString()); } // update the buttons DeletePackagesButton.Visible = false; CloseButton.Text = "OK"; // set the hidden form element PackagesSuccessfullyDeleted to a // comma-separated list of IDs of packages that were successfully // deleted, and enable the client-side script that communicates this // information to the parent page PackagesSuccessfullyDeleted.Value = String.Join(",", deleted.ToArray()); UpdateParentPageScript.Visible = true; }
/// <summary> /// Gets the attempt id of the requested attempt. If the page is provided a learner assignment id and /// the attempt associated with the assignment doesn't exist, then one is created. If the user does not have /// access to the attempt, or the requested view of the attempt, or there is no /// attempt (such as non-elearning content) then false is returned. /// </summary> /// <param name="showErrorPage"></param> /// <param name="attemptId"></param> /// <returns></returns> public override bool TryGetAttemptId(bool showErrorPage, out AttemptItemIdentifier attemptId) { // Initialize out parameter attemptId = null; if (learnerAssignmentGuidIdHasBeenSet == false) { Guid learnerAssignmentGuidId; if (!TryProcessLearnerAssignmentIdParameter(showErrorPage, out learnerAssignmentGuidId)) { // In this case, if the parameter was not valid (eg, it's not a number), the error is already registered. // So just return. return(false); } LearnerAssignmentGuidId = learnerAssignmentGuidId; } // Put this operation in a transaction because if the attempt has not been started, we'll start the attempt // and update the assignment. Both should succeed or both should fail. LearnerAssignmentProperties la; TransactionOptions options = new TransactionOptions(); options.IsolationLevel = System.Transactions.IsolationLevel.RepeatableRead; using (LearningStoreTransactionScope scope = new LearningStoreTransactionScope(options)) { // Must force a read of assignment data so that it's read in the same transaction that it might be updated. la = GetLearnerAssignment(true); SessionView view; if (!TryGetSessionView(true, out view)) { return(false); } if (la.Assignment.IsELearning) { // This is e-learning content m_isELearning = true; // Accessing LearnerAssignment (above) would have checked the database and retrieve any information available about // the assignment, including its attempt id, if it exists. If the LearnerAssignment information is valid // but there's no attempt, the AttemptId property will be null if (la.AttemptId == null) { // Only create the attempt if this is a request for Execute view if (view == SessionView.Execute) { if (!FileExistsInSharePoint(la.Assignment.Location)) { if (showErrorPage) { RegisterError(SlkFrameset.FRM_PackageNotFoundTitle, SlkFrameset.FRM_PackageNotFound, false); } return(false); } SlkStore.StartAttemptOnLearnerAssignment(LearnerAssignmentGuidId); // Force a reset of internal data regarding the current learner assignment la = GetLearnerAssignment(true); } else { // This is an error condition, since in other cases, the attempt must already exist. // Use private method to get the right error message. if (!ProcessViewRequest(la.Status, view)) { return(false); } } } else { // Attempt is already created. Verify the user has access to it and that the package exists. if (!ProcessViewRequest(la.Status, view)) { return(false); } if (!FileExistsInSharePoint(la.Assignment.Location)) { if (showErrorPage) { RegisterError(SlkFrameset.FRM_PackageNotFoundTitle, SlkFrameset.FRM_PackageNotFound, false); } return(false); } } // Attempt exists, set the out parameter attemptId = la.AttemptId; } else { // Is not e-learning assignment m_isELearning = false; // Verify that the learner can see the assignment. if (view == SessionView.Execute) { if (!FileExistsInSharePoint(la.Assignment.Location)) { if (showErrorPage) { RegisterError(SlkFrameset.FRM_PackageNotFoundTitle, SlkFrameset.FRM_PackageNotFound, false); } return(false); } // Mark the assignment as started if (la.Status != LearnerAssignmentState.Active) { la.Start(); } } else { // Verify this is a view they have access to given the state of the assignment. No need to check // return value, as non-elearning content always returns false from this method. if (!ProcessViewRequest(la.Status, view)) { return(false); } if (!FileExistsInSharePoint(la.Assignment.Location)) { if (showErrorPage) { RegisterError(SlkFrameset.FRM_PackageNotFoundTitle, SlkFrameset.FRM_PackageNotFound, false); } return(false); } } } scope.Complete(); } return(attemptId != null); }
protected void Page_Load(object sender, EventArgs e) { // set <attemptId> to the ID of this attempt AttemptItemIdentifier attemptId = new AttemptItemIdentifier( Convert.ToInt64(Request.QueryString["AttemptId"], CultureInfo.InvariantCulture)); // set <previousEntryId> to the ID of the sequencing log entry that we most recently // displayed; newer entries than that will be highlighted long previousEntryId; string value = Request.QueryString["PreviousEntryId"]; if (value == null) { previousEntryId = long.MaxValue; } else { previousEntryId = Convert.ToInt64(value, CultureInfo.InvariantCulture); } try { // create a job to execute two queries LearningStoreJob job = LStore.CreateJob(); // first query: get the package name and organization title of this attempt LearningStoreQuery query = LStore.CreateQuery(Schema.MyAttemptsAndPackages.ViewName); query.AddColumn(Schema.MyAttemptsAndPackages.PackageFileName); query.AddColumn(Schema.MyAttemptsAndPackages.OrganizationTitle); query.AddCondition(Schema.MyAttemptsAndPackages.AttemptId, LearningStoreConditionOperator.Equal, attemptId); job.PerformQuery(query); // second query: get the contents of the sequencing log for this attempt query = LStore.CreateQuery(Schema.SequencingLog.ViewName); query.AddColumn(Schema.SequencingLog.Id); query.AddColumn(Schema.SequencingLog.Timestamp); query.AddColumn(Schema.SequencingLog.EventType); query.AddColumn(Schema.SequencingLog.NavigationCommand); query.AddColumn(Schema.SequencingLog.Message); query.SetParameter(Schema.SequencingLog.AttemptId, attemptId); query.AddSort(Schema.SequencingLog.Id, LearningStoreSortDirection.Descending); job.PerformQuery(query); // execute the job ReadOnlyCollection <object> results = job.Execute(); DataTable attemptInfoDataTable = (DataTable)results[0]; DataTable sequencingLogDataTable = (DataTable)results[1]; // extract information from the first query into local variables DataRow attemptInfo = attemptInfoDataTable.Rows[0]; string packageFileName; LStoreHelper.CastNonNull(attemptInfo[Schema.MyAttemptsAndPackages.PackageFileName], out packageFileName); string organizationTitle; LStoreHelper.CastNonNull(attemptInfo[Schema.MyAttemptsAndPackages.OrganizationTitle], out organizationTitle); // set <trainingName> to the name to use for this attempt string trainingName; if (organizationTitle.Length == 0) { trainingName = packageFileName; } else { trainingName = String.Format("{0} - {1}", packageFileName, organizationTitle); } // copy <trainingName> to the UI TrainingName.Text = Server.HtmlEncode(trainingName); // set <maxLogEntryId> to the highest-numbered log entry ID -- which is the first one, // since they're sorted by descending entry ID SequencingLogEntryItemIdentifier maxLogEntryId; if (sequencingLogDataTable.Rows.Count > 0) { DataRow dataRow = sequencingLogDataTable.Rows[0]; LStoreHelper.CastNonNull(dataRow[Schema.SequencingLog.Id], out maxLogEntryId); } else { maxLogEntryId = new SequencingLogEntryItemIdentifier(-1); } // loop once for each item in the sequencing log foreach (DataRow dataRow in sequencingLogDataTable.Rows) { // extract information from <dataRow> into local variables SequencingLogEntryItemIdentifier logEntryId; LStoreHelper.CastNonNull(dataRow[Schema.SequencingLog.Id], out logEntryId); DateTime?time; LStoreHelper.Cast(dataRow[Schema.SequencingLog.Timestamp], out time); SequencingEventType?eventType; LStoreHelper.Cast(dataRow[Schema.SequencingLog.EventType], out eventType); NavigationCommand?navigationCommand; LStoreHelper.Cast(dataRow[Schema.SequencingLog.NavigationCommand], out navigationCommand); string message; LStoreHelper.CastNonNull(dataRow[Schema.SequencingLog.Message], out message); // begin the HTML table row TableRow htmlRow = new TableRow(); // highlight this row if it's new since the last refresh if (logEntryId.GetKey() > previousEntryId) { htmlRow.CssClass = "Highlight"; } // add the "ID" HTML cell TableCell htmlCell = new TableCell(); htmlCell.CssClass = "Id_"; htmlCell.Wrap = false; htmlCell.Text = NoBr(Server.HtmlEncode(logEntryId.GetKey().ToString())); htmlRow.Cells.Add(htmlCell); // add the "Time" HTML cell htmlCell = new TableCell(); htmlCell.CssClass = "Time_"; htmlCell.Wrap = false; htmlCell.Text = NoBr(Server.HtmlEncode(String.Format("{0:d} {0:t}", time))); htmlRow.Cells.Add(htmlCell); // add the "EventType" HTML cell htmlCell = new TableCell(); htmlCell.CssClass = "EventType_"; htmlCell.Wrap = false; htmlCell.Text = NoBr(Server.HtmlEncode(eventType.ToString())); htmlRow.Cells.Add(htmlCell); // add the "NavigationCommand" HTML cell htmlCell = new TableCell(); htmlCell.CssClass = "NavigationCommand_"; htmlCell.Wrap = false; htmlCell.Text = NoBr(Server.HtmlEncode(navigationCommand.ToString())); htmlRow.Cells.Add(htmlCell); // add the "Message" HTML cell htmlCell = new TableCell(); htmlCell.CssClass = "Message_"; htmlCell.Wrap = false; htmlCell.Text = Server.HtmlEncode(message); htmlRow.Cells.Add(htmlCell); // end the table HTML row; add it to the HTML table LogGrid.Rows.Add(htmlRow); } // update <RefreshLink> RefreshLink.NavigateUrl = String.Format("?AttemptId={0}&PreviousEntryId={1}", attemptId.GetKey(), maxLogEntryId.GetKey()); } catch (Exception ex) { // an unexpected error occurred -- display a generic message that doesn't include the // exception message (since that message may include sensitive information), and write // the exception message to the event log LogTitle.Visible = false; LogContents.Visible = false; ErrorMessage.Visible = true; ErrorMessage.Controls.Add(new System.Web.UI.LiteralControl( Server.HtmlEncode("A serious error occurred. Please contact your system administrator. More information has been written to the server event log."))); LogEvent(System.Diagnostics.EventLogEntryType.Error, "An exception occurred while accessing the sequencing log for attempt #{0}:\n\n{1}\n\n", attemptId.GetKey(), ex.ToString()); } }
/// <summary> /// Helper function to get the AttemptId query parameter. This method assumes the parameter is required. If /// it does not exist or is not numeric, the error page is shown. This method does not check LearningStore. /// </summary> /// <param name="isRequired">If true, the error page is shown if the value is not provided.</param> /// <param name="attemptId">The attempt id.</param> /// <returns>If false, the value did not exist or was not valid. The application should not continue with /// page processing.</returns> public bool ProcessAttemptIdParameter(bool showErrorPage, out AttemptItemIdentifier attemptId) { string attemptParam = null; bool isValid = true; attemptId = null; if (!GetRequiredParameter(FramesetQueryParameter.AttemptId, out attemptParam)) return false; // Try converting it to a long value. It must be positive. try { long attemptKey = long.Parse(attemptParam, NumberFormatInfo.InvariantInfo); if (attemptKey <= 0) isValid = false; else attemptId = new AttemptItemIdentifier(attemptKey); } catch (FormatException) { isValid = false; } if (!isValid && showErrorPage) { RegisterError(ResHelper.GetMessage(IUDICO.TestingSystem.Localization.getMessage("FRM_InvalidParameterTitle"), FramesetQueryParameter.AttemptId), ResHelper.GetMessage(IUDICO.TestingSystem.Localization.getMessage("FRM_InvalidParameterMsg"), FramesetQueryParameter.AttemptId, attemptParam), false); } return isValid; }
public IEnumerable<AnswerResult> GetAnswers(AttemptResult attemptResult) { LearningStoreJob job = this.LStore.CreateJob(); var attemptId = new AttemptItemIdentifier(attemptResult.AttemptId); this.RequestInteractionResultsByAttempt(job, attemptId); var dataTable = job.Execute<DataTable>(); foreach (DataRow dataRow in dataTable.AsEnumerable()) { ActivityAttemptItemIdentifier activityAttemptItemId; LStoreHelper.CastNonNull( dataRow[Schema.InteractionResultsByAttempt.ActivityAttemptId], out activityAttemptItemId); long activityAttemptId = activityAttemptItemId.GetKey(); ActivityPackageItemIdentifier activityPackageItemId; LStoreHelper.CastNonNull( dataRow[Schema.InteractionResultsByAttempt.ActivityPackageId], out activityPackageItemId); long activityPackageId = activityPackageItemId.GetKey(); string activityTitle; LStoreHelper.CastNonNull(dataRow[Schema.InteractionResultsByAttempt.ActivityTitle], out activityTitle); InteractionItemIdentifier interactionItemId; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.InteractionId], out interactionItemId); long? interactionId = null; if (interactionItemId != null) { interactionId = interactionItemId.GetKey(); } CompletionStatus completionStatus; LStoreHelper.CastNonNull( dataRow[Schema.InteractionResultsByAttempt.CompletionStatus], out completionStatus); var iudicoCompletionStatus = (Common.Models.Shared.Statistics.CompletionStatus)completionStatus; SuccessStatus? successStatus; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.SuccessStatus], out successStatus); var iudicoSuccessStatus = (Common.Models.Shared.Statistics.SuccessStatus?)successStatus; bool? learnerResponseBool; LStoreHelper.Cast( dataRow[Schema.InteractionResultsByAttempt.LearnerResponseBool], out learnerResponseBool); string learnerResponseString; LStoreHelper.Cast( dataRow[Schema.InteractionResultsByAttempt.LearnerResponseString], out learnerResponseString); double? learnerResponseNumeric; LStoreHelper.Cast( dataRow[Schema.InteractionResultsByAttempt.LearnerResponseNumeric], out learnerResponseNumeric); object learnerResponse = null; if (learnerResponseBool != null) { learnerResponse = learnerResponseBool; } if (learnerResponseString != null) { learnerResponse = learnerResponseString; } if (learnerResponseNumeric != null) { learnerResponse = learnerResponseNumeric; } string correctResponse; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.CorrectResponse], out correctResponse); InteractionType? interactionType; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.InteractionType], out interactionType); Common.Models.Shared.Statistics.InteractionType? learnerResponseType = null; if (interactionType != null) { learnerResponseType = (Common.Models.Shared.Statistics.InteractionType)interactionType; } float? minScore; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.MinScore], out minScore); float? maxScore; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.MaxScore], out maxScore); float? rawScore; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.RawScore], out rawScore); float? scaledScore; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.ScaledScore], out scaledScore); string primaryResourceFromManifest; LStoreHelper.Cast(dataRow[Schema.InteractionResultsByAttempt.PrimaryResourceFromManifest], out primaryResourceFromManifest); // Create AnswerResult object var answerResult = new AnswerResult( activityAttemptId, activityPackageId, activityTitle, interactionId, iudicoCompletionStatus, iudicoSuccessStatus, attemptResult, learnerResponse, correctResponse, learnerResponseType, minScore, maxScore, rawScore, scaledScore, primaryResourceFromManifest); yield return answerResult; } }