public async Task <IActionResult> Answer([FromRoute] CommonAPI_TestSectionIdDTO sectionIdDTO, [FromRoute] CommonAPI_TestQuestionIdDTO questionIdDTO, [FromBody] MemberAPI_CommonTestAnswerDTO answerDTO) { var(errorCode, response) = await _attemptService.MemberAPI_Answer(sectionIdDTO, questionIdDTO, answerDTO); return(this.ResultResponse(errorCode, response)); }
public static (bool, OperationErrorMessages, object) ApplyAnswer(Dictionary <string, AttemptsDB_SectionDTO> sections, string sectionId, string questionId, MemberAPI_CommonTestAnswerDTO testAnswerDTO) { if (!sections.ContainsKey(sectionId)) { return(false, OperationErrorMessages.SectionNotFound, null); } var questions = sections[sectionId].Questions; if (!questions.ContainsKey(questionId)) { return(false, OperationErrorMessages.QuestionNotFound, null); } var question = questions[questionId]; if (question.Type == QuestionTypes.SingleChoice) { var selectedOption = testAnswerDTO.SelectedOption; if (selectedOption != null) { var optionsContainer = BsonSerializer.Deserialize <AttemptsDB_ChoiceOptionsContainer>(question.Options); if (selectedOption >= optionsContainer.Options.Length) { return(false, OperationErrorMessages.SelectedOptionOutOfRange, null); } for (var i = 0; i < optionsContainer.Options.Length; i++) { optionsContainer.Options[i].Chosen = i == selectedOption; } question.Options = optionsContainer.ToBsonDocument(); } } else if (question.Type == QuestionTypes.MultipleChoice) { var selectedOptions = testAnswerDTO.SelectedOptions; if (selectedOptions != null) { var optionsContainer = BsonSerializer.Deserialize <AttemptsDB_ChoiceOptionsContainer>(question.Options); var optionsCount = optionsContainer.Options.Length; var uniques = new HashSet <int>(); for (var i = 0; i < selectedOptions.Length; i++) { if (selectedOptions[i] >= optionsCount) { return(false, OperationErrorMessages.SelectedOptionOutOfRange, null); } if (!uniques.Add(selectedOptions[i])) { return(false, OperationErrorMessages.NonUniqueOption, new CommonAPI_ErrorDTO { ErrorSubject = selectedOptions[i] }); } } for (var i = 0; i < optionsCount; i++) { optionsContainer.Options[i].Chosen = selectedOptions.Contains(i); } question.Options = optionsContainer.ToBsonDocument(); } } else if (question.Type == QuestionTypes.Matching) { var leftSequence = testAnswerDTO.LeftSequence; var rightSequence = testAnswerDTO.RightSequence; if (leftSequence != null && rightSequence != null) { var optionsContainer = BsonSerializer.Deserialize <AttemptsDB_MatchingOptionsContainer>(question.Options); var optionsCount = optionsContainer.LeftSequence.Length; if (leftSequence.Length != optionsCount) { return(false, OperationErrorMessages.WrongOptionsCount, new CommonAPI_ErrorDTO { ErrorSubject = "left" }); } if (rightSequence.Length != optionsCount) { return(false, OperationErrorMessages.WrongOptionsCount, new CommonAPI_ErrorDTO { ErrorSubject = "right" }); } var leftUniques = new HashSet <int>(); var rightUniques = new HashSet <int>(); for (var i = 0; i < leftSequence.Length; i++) { if (leftSequence[i] >= optionsCount) { return(false, OperationErrorMessages.SelectedOptionOutOfRange, new CommonAPI_ErrorDTO { ErrorSubject = new object[] { "left", leftSequence[i] } }); } if (rightSequence[i] >= optionsCount) { return(false, OperationErrorMessages.SelectedOptionOutOfRange, new CommonAPI_ErrorDTO { ErrorSubject = new object[] { "right", rightSequence[i] } }); } if (!leftUniques.Add(leftSequence[i])) { return(false, OperationErrorMessages.NonUniqueOption, new CommonAPI_ErrorDTO { ErrorSubject = new object[] { "left", leftSequence[i] } }); } if (!rightUniques.Add(rightSequence[i])) { return(false, OperationErrorMessages.NonUniqueOption, new CommonAPI_ErrorDTO { ErrorSubject = new object[] { "right", rightSequence[i] } }); } } var tempLeftSequence = new AttemptsDB_PositionalOption[optionsCount]; var tempRightSequence = new AttemptsDB_PositionalOption[optionsCount]; for (var i = 0; i < optionsCount; i++) { tempLeftSequence[i] = optionsContainer.LeftSequence[leftSequence[i]]; tempRightSequence[i] = optionsContainer.RightSequence[rightSequence[i]]; } optionsContainer.LeftSequence = tempLeftSequence; optionsContainer.RightSequence = tempRightSequence; question.Options = optionsContainer.ToBsonDocument(); } } else if (question.Type == QuestionTypes.Sequence) { var sequence = testAnswerDTO.Sequence; if (sequence != null) { var optionsContainer = BsonSerializer.Deserialize <AttemptsDB_SequenceOptionsContainer>(question.Options); var optionsCount = optionsContainer.Sequence.Length; if (sequence.Length != optionsCount) { return(false, OperationErrorMessages.WrongOptionsCount, null); } var uniques = new HashSet <int>(); for (var i = 0; i < sequence.Length; i++) { if (sequence[i] >= optionsCount) { return(false, OperationErrorMessages.SelectedOptionOutOfRange, new CommonAPI_ErrorDTO { ErrorSubject = sequence[i] }); } if (!uniques.Add(sequence[i])) { return(false, OperationErrorMessages.NonUniqueOption, new CommonAPI_ErrorDTO { ErrorSubject = sequence[i] }); } } for (var i = 0; i < optionsCount; i++) { optionsContainer.Sequence[i] = optionsContainer.Sequence[sequence[i]]; } question.Options = optionsContainer.ToBsonDocument(); } } else if (question.Type == QuestionTypes.FillIn) { var fills = testAnswerDTO.Fills; if (fills != null) { var optionsContainer = BsonSerializer.Deserialize <AttemptsDB_FillInOptionsContainer>(question.Options); var options = optionsContainer.Options; var blanksCount = optionsContainer.Options .Where(option => option.IsBlank ).ToArray() .Length; if (fills.Length != blanksCount) { return(false, OperationErrorMessages.WrongOptionsCount, null); } var j = 0; for (var i = 0; i < optionsContainer.Options.Length; i++) { if (optionsContainer.Options[i].IsBlank) { optionsContainer.Options[i].Text = fills[j]; j++; } } question.Options = optionsContainer.ToBsonDocument(); } } question.Touched = true; question.BlurTime += testAnswerDTO.BlurTimeAddition.Value; question.TotalTime += testAnswerDTO.TotalTimeAddition.Value; sections[sectionId].Questions[questionId] = question; return(true, OperationErrorMessages.NoError, sections); }