public async Task <IActionResult> OnPostAsync(int?id, string ReturnPath) { if (id == null) { return(NotFound()); } Question = await _context.QuizQuestions.FindAsync((int)id.Value); if (Question == null) { return(RedirectToPage("/error", new { errorMessage = "That's Odd! We were unable to retrieve this Question... Maybe try that again?" })); } // confirm our user is a valid PBE User. IdentityUser user = await _userManager.GetUserAsync(User); PBEUser = await QuizUser.GetOrAddPBEUserAsync(_context, user.Email); if (!PBEUser.IsValidPBEQuestionBuilder()) { return(RedirectToPage("/error", new { errorMessage = "Sorry! You do not have sufficient rights to edit a PBE question" })); } // Questions and Answers are not actually deleted, because they are used to calculate Stats so we just set to IsDeleted = true. if (Question != null) { _context.Attach(Question).State = EntityState.Modified; Question.Modified = DateTime.Now; Question.IsDeleted = true; await _context.SaveChangesAsync(); } switch (ReturnPath) { case "Questions": return(RedirectToPage("./Questions", new { BibleId = Question.BibleId, BookNumber = Question.BookNumber, Chapter = Question.Chapter })); // break; not needed unreachable case "ChallengedQuestions": return(RedirectToPage("ChallengedQuestions", new { BibleId = Question.BibleId })); // break; not needed unreachable default: return(RedirectToPage("./Questions", new { BibleId = Question.BibleId, BookNumber = Question.BookNumber, Chapter = Question.Chapter })); // break; not needed unreachable } }
public async Task <IActionResult> OnPostAsync(int?id) { if (id == null) { return(NotFound()); } try { BookList = await _context.QuizBookLists.Include(B => B.QuizBookListBookMaps).Where(B => B.Id == id).SingleAsync(); } catch { return(RedirectToPage("/error", new { errorMessage = "That's Odd! We were unable to retrieve this BookList... Maybe try that again" })); } // confirm Path Owner IdentityUser user = await _userManager.GetUserAsync(User); PBEUser = await QuizUser.GetOrAddPBEUserAsync(_context, user.Email); if (!PBEUser.IsQuizModerator()) { return(RedirectToPage("/error", new { errorMessage = "Sorry! You do not have sufficient rights to delete a PBE BookList" })); } // We only ever soft delete a BookList but we do delete the maps. // First we need to iterate through each BookList Map and delete them, these are a leaf node so this should be OK. foreach (QuizBookListBookMap book in BookList.QuizBookListBookMaps) { _context.QuizBookListBookMaps.Remove(book); } await _context.SaveChangesAsync(); // Let's track this event // _ = await Path.RegisterEventAsync(_context, EventType.PathDeleted, Path.Id.ToString()); // Then we set the BookList to isDeleted if (BookList != null) { _context.Attach(BookList).State = EntityState.Modified; BookList.Modified = DateTime.Now; BookList.IsDeleted = true; await _context.SaveChangesAsync(); } return(RedirectToPage("./BookLists")); }
public async Task <IActionResult> OnPostAsync(int?id) { if (id == null) { return(NotFound()); } try { Template = await _context.PredefinedQuizzes.Include(T => T.PredefinedQuizQuestions).Where(T => T.Id == id).SingleAsync(); } catch { return(RedirectToPage("/error", new { errorMessage = "That's Odd! We were unable to retrieve this Template... Maybe try that again?" })); } // confirm Template Owner IdentityUser user = await _userManager.GetUserAsync(User); PBEUser = await QuizUser.GetOrAddPBEUserAsync(_context, user.Email); if (Template.QuizUser != PBEUser) { return(RedirectToPage("/error", new { errorMessage = "Sorry! Only a Template Owner may delete a Template" })); } // First we need to iterate through each Step and delete them one by one, steps are a leaf node so this should be OK. foreach (PredefinedQuizQuestion Question in Template.PredefinedQuizQuestions) { _context.PredefinedQuizQuestions.Remove(Question); } await _context.SaveChangesAsync(); // Let's track this event // _ = await Path.RegisterEventAsync(_context, EventType.PathDeleted, Path.Id.ToString()); // Then we set the Template to isDeleted. if (Template != null) { _context.Attach(Template).State = EntityState.Modified; Template.Modified = DateTime.Now; Template.IsDeleted = true; await _context.SaveChangesAsync(); } return(RedirectToPage("./Templates")); }
public async Task <IActionResult> OnPostAsync(int?id) { if (id == null) { return(NotFound()); } try { Path = await _context.Paths.Include(P => P.PathNodes).Where(P => P.Id == id).SingleAsync(); } catch { return(RedirectToPage("/error", new { errorMessage = "That's Odd! We were unable to retrieve this path... Not sure what to tell you!" })); } // confirm Path Owner IdentityUser user = await _userManager.GetUserAsync(User); if (!Path.IsPathOwner(user.Email)) { return(RedirectToPage("/error", new { errorMessage = "Sorry! Only a Path Owner may delete a Path" })); } // First we need to iterate through each Step and delete them one by one, steps are a leaf node so this should be OK. foreach (PathNode step in Path.PathNodes) { _context.PathNodes.Remove(step); } await _context.SaveChangesAsync(); // Let's track this event _ = await Path.RegisterEventAsync(_context, EventType.PathDeleted, Path.Id.ToString()); // Then we set the Path to isDeleted, we also unPublish it in case a filter is incorrectly not checking for deleted. if (Path != null) { _context.Attach(Path).State = EntityState.Modified; Path.Modified = DateTime.Now; Path.IsPublished = false; Path.IsDeleted = true; await _context.SaveChangesAsync(); } return(RedirectToPage("./MyPaths")); }
public async Task <IActionResult> OnPostAsync(int?id) { if (id == null) { return(NotFound()); } try { Quiz = await _context.QuizGroupStats.Where(Q => Q.Id == id).SingleAsync(); } catch { return(RedirectToPage("/error", new { errorMessage = "That's Odd! We were unable to retrieve this Quiz... Maybe try that again?" })); } // confirm Quiz Owner IdentityUser user = await _userManager.GetUserAsync(User); PBEUser = await QuizUser.GetOrAddPBEUserAsync(_context, user.Email); if (Quiz.QuizUser != PBEUser) { return(RedirectToPage("/error", new { errorMessage = "Sorry! Only a Quiz Owner may delete a Quiz" })); } // Let's track this event // _ = await Path.RegisterEventAsync(_context, EventType.PathDeleted, Path.Id.ToString()); // Then we set the Quiz to isDeleted, we want to keep these around for refrence to QuizQuestion Stats. if (Quiz != null) { _context.Attach(Quiz).State = EntityState.Modified; Quiz.Modified = DateTime.Now; Quiz.IsDeleted = true; await _context.SaveChangesAsync(); } return(RedirectToPage("./Quizzes")); }
// To protect from overposting attacks, please enable the specific properties you want to bind to, for // more details see https://aka.ms/RazorPagesCRUD. public async Task <IActionResult> OnPostAsync() { if (!ModelState.IsValid) { // Populate Step for display _ = await Step.AddBookNameAsync(_context, BibleId); Step.Verses = await Step.GetBibleVersesAsync(_context, BibleId, false, false); // and now we need a Verse Select List ViewData["VerseSelectList"] = new SelectList(Step.Verses, "Verse", "Verse"); ViewData["TargetPage"] = "AddStep"; return(Page()); } // Now let's validate a few things, first lets go grab the path. Path = await _context.Paths.FindAsync(Step.PathId); if (Path == null) { return(RedirectToPage("/error", new { errorMessage = "That's Odd! We weren't able to find this Path" })); } // confirm our owner is a valid path editor i.e. owner or the path is publicly editable IdentityUser user = await _userManager.GetUserAsync(User); if (!Path.IsValidPathEditor(user.Email)) { return(RedirectToPage("/error", new { errorMessage = "Sorry! You do not have sufficient rights to add to this Path" })); } if (!Path.IsPathOwner(user.Email)) { _ = await Path.RegisterEventAsync(_context, EventType.NonOwnerEdit, user.Email); } // Now let's create an empty Step aka. PathNode object so we can put only our validated properties onto it. var emptyStep = new PathNode { Created = DateTime.Now, Modified = DateTime.Now }; if (await TryUpdateModelAsync <PathNode>( emptyStep, "Step", // Prefix for form value. S => S.StartVerse, S => S.EndVerse, S => S.PathId, S => S.BookNumber, S => S.Chapter, S => S.Position)) { // What we get for Position is actually that of the previous node in the path. // We want to replace that with a temporary position that we'll update later. int PreviousNodePosition = emptyStep.Position; emptyStep.Position = PreviousNodePosition + 5; _context.PathNodes.Add(emptyStep); await _context.SaveChangesAsync(); // Now we need to update the Path Object with some calculated properties if (!Path.IsPathOwner(user.Email)) { _ = await Path.RegisterEventAsync(_context, EventType.NonOwnerEdit, user.Email); } // Prepare to update some properties on Path _context.Attach(Path); Path.Length = await Path.GetPathVerseCountAsync(_context); Path.StepCount = Path.PathNodes.Count; Path.Modified = DateTime.Now; // Save our now updated Path Object. await _context.SaveChangesAsync(); // Finally we need to re-position each node in the path to ensure safe ordering _ = await Path.RedistributeStepsAsync(_context); return(RedirectToPage("/Paths/Steps", new { PathId = Path.Id })); } //_context.PathNodes.Add(PathNodes); //await _context.SaveChangesAsync(); return(RedirectToPage("./Index")); }
// To protect from overposting attacks, please enable the specific properties you want to bind to, for // more details see https://aka.ms/RazorPagesCRUD. public async Task <IActionResult> OnPostAsync(int Id) { if (!ModelState.IsValid) { // Populate Step for display _ = await Step.AddBookNameAsync(_context, BibleId); Step.Verses = await Step.GetBibleVersesAsync(_context, BibleId, false, false); // and now we need a Verse Select List ViewData["VerseSelectList"] = new SelectList(Step.Verses, "Verse", "Verse"); return(Page()); } // Now let's validate a few things, first lets go grab the Step and Path PathNode StepToUpdate = await _context.PathNodes.FindAsync(Id); Path = await _context.Paths.FindAsync(Step.PathId); if (Path == null) { return(RedirectToPage("/error", new { errorMessage = "That's Odd! We weren't able to find this Path" })); } if (StepToUpdate == null) { return(RedirectToPage("/error", new { errorMessage = "That's Odd! We weren't able to find this Step" })); } if (StepToUpdate.PathId != Path.Id) { return(RedirectToPage("/error", new { errorMessage = "That's Odd! Path/Step mismatch" })); } BibleId = await Path.GetValidBibleIdAsync(_context, BibleId); // confirm our owner is a valid path editor i.e. owner or the path is publicly editable IdentityUser user = await _userManager.GetUserAsync(User); if (!Path.IsValidPathEditor(user.Email)) { return(RedirectToPage("/error", new { errorMessage = "Sorry! You do not have sufficient rights to add to this Path" })); } if (!Path.IsPathOwner(user.Email)) { _ = await Path.RegisterEventAsync(_context, EventType.NonOwnerEdit, user.Email); } if (await TryUpdateModelAsync <PathNode>( StepToUpdate, "Step", // Prefix for form value. S => S.StartVerse, S => S.EndVerse, S => S.BookNumber, S => S.Chapter)) { StepToUpdate.Modified = DateTime.Now; await _context.SaveChangesAsync(); // Now we need to update the Path Object with some calculated properties if (!Path.IsPathOwner(user.Email)) { _ = await Path.RegisterEventAsync(_context, EventType.NonOwnerEdit, user.Email); } // Prepare to update some properties on Path _context.Attach(Path); Path.Modified = DateTime.Now; // Save our now updated Path Object. await _context.SaveChangesAsync(); } return(RedirectToPage("/Paths/Steps", new { PathId = Path.Id })); }
public async Task <IActionResult> OnGetAsync(int GroupId, int TeamId, int StepId) { Group = await _context.GameGroups.FindAsync(GroupId); if (Group == null) { return(RedirectToPage("/error", new { errorMessage = "That's Odd! We weren't able to find that Group" })); } Team = await _context.GameTeams.FindAsync(TeamId); if (Team == null) { return(RedirectToPage("/error", new { errorMessage = "That's Odd! We were not able to find that Team" })); } if (Team.GroupId != Group.Id) { return(RedirectToPage("/error", new { errorMessage = "That's Odd! The Team and Group do not match" })); } string BibleId = await GameTeam.GetValidBibleIdAsync(_context, null); // Now let's check that StepId if (StepId == Team.CurrentStepId) { PathNode CurrentStep = await _context.PathNodes.FindAsync(Team.CurrentStepId); if (CurrentStep == null) { return(RedirectToPage("/error", new { errorMessage = "That's Very Odd! We couldn't find Current Step" })); } _ = await CurrentStep.AddGenericStepPropertiesAsync(_context, BibleId); _ = await CurrentStep.AddPathStepPropertiesAsync(_context); // We have a winner! Let's update the Team Object _context.Attach(Team); Team.Modified = DateTime.Now; if (CurrentStep.FWStepId > 0) { Team.CurrentStepId = CurrentStep.FWStepId; Team.StepNumber = Team.StepNumber + 1; Team.BoardState = (int)GameTeam.GameBoardState.WordSelect; } else { Team.BoardState = (int)GameTeam.GameBoardState.Completed; } await _context.SaveChangesAsync(); // We need to add the Quotes around the TeamID, then signal the StateChange string GroupName = "\"" + Team.Id.ToString() + "\""; await _hubContext.Clients.Group(GroupName).SendAsync("StateChange"); return(RedirectToPage("Team", new { GroupId = Team.GroupId, TeamId = Team.Id, Message = "Good Job! You're on the right Path" })); } else { _context.Attach(Team); Team.Modified = DateTime.Now; Team.BoardState = (int)GameTeam.GameBoardState.WordSelectOffPath; await _context.SaveChangesAsync(); // We need to add the Quotes around the TeamID, then signal the StateChange string GroupName = "\"" + Team.Id.ToString() + "\""; await _hubContext.Clients.Group(GroupName).SendAsync("StateChange"); return(RedirectToPage("Team", new { GroupId = Team.GroupId, TeamId = Team.Id, Message = "Uh Oh! You've drifted off Path" })); } }
// To protect from overposting attacks, please enable the specific properties you want to bind to, for // more details see https://aka.ms/RazorPagesCRUD. public async Task <IActionResult> OnPostAsync(string BibleId, int QuizId) { if (!ModelState.IsValid) { // Something bad has happened let's go get a new quiz question. UserMessage = "Something has gone wrong! We were unable to save the results for that last question"; return(RedirectToPage("Quiz", new { BibleId, QuizId, Message = UserMessage })); } IdentityUser user = await _userManager.GetUserAsync(User); PBEUser = await QuizUser.GetOrAddPBEUserAsync(_context, user.Email); // Static method not requiring an instance if (!PBEUser.IsValidPBEQuizHost()) { return(RedirectToPage("/error", new { errorMessage = "Sorry! You do not have sufficient rights to host a PBE Quiz" })); } this.BibleId = await Bible.GetValidPBEBibleIdAsync(_context, BibleId); // Let's grab the Quiz Object in order to update it. Quiz = await _context.QuizGroupStats.FindAsync(QuizId); if (Quiz == null) { return(RedirectToPage("/error", new { errorMessage = "That's Odd... We were unable to find this Quiz" })); } if (Quiz.QuizUser != PBEUser) { return(RedirectToPage("/error", new { errorMessage = "Sorry! Only a Quiz Owner can award points during a Quiz" })); } // We need to upate the Question object as well so let's go grab it. QuizQuestion QuestionToUpdate = await _context.QuizQuestions.FindAsync(Question.Id); if (QuestionToUpdate == null) { return(RedirectToPage("/error", new { errorMessage = "That's Odd... We were unable to find this Question so we can't update it" })); } // Now we award the points... let's get this right: // Let's prevent posting an anomalous number of points. int QuestionPointsPossible = QuestionToUpdate.Points; if (Question.PointsAwarded > QuestionPointsPossible) { Question.PointsAwarded = QuestionPointsPossible; } if (Question.PointsAwarded < 0) { Question.PointsAwarded = 0; } // Update the Quiz Object: _context.Attach(Quiz); Quiz.PointsPossible += QuestionPointsPossible; Quiz.PointsAwarded += Question.PointsAwarded; Quiz.QuestionsAsked += 1; Quiz.Modified = DateTime.Now; // Update the Question Object _context.Attach(QuestionToUpdate); QuestionToUpdate.LastAsked = DateTime.Now; // We've had some challenges with users challenging many questions often with no comment. // We will do a user check and make sure our user isn't blocked, if they are we silently fail the challenge. // TODO: We should revisit the silent fail if it becomes a problem. if (Question.Challenged && !PBEUser.IsQuestionBuilderLocked) { QuestionToUpdate.Challenged = true; QuestionToUpdate.ChallengeComment = Question.ChallengeComment; QuestionToUpdate.ChallengedBy = PBEUser.Email; } // Save both of these changes. await _context.SaveChangesAsync(); // And next let's make sure we log this event. // BUG: Note we've had a pretty significant data bug prior to 6/8/2019 where we were setting Points to the cumulative quizGroupStat.PointsAwarded vs. the non-cumulative PointsAwardedByJudge... so all data prior to this date is wrong. await QuestionToUpdate.RegisterEventAsync(_context, QuestionEventType.QuestionPointsAwarded, PBEUser.Id, null, Quiz.Id, Question.PointsAwarded); return(RedirectToPage("Quiz", new { BibleId, QuizId })); }
// To protect from overposting attacks, please enable the specific properties you want to bind to, for // more details see https://aka.ms/RazorPagesCRUD. public async Task <IActionResult> OnPostAsync(int Id) { // confirm our user is a valid PBE User. IdentityUser user = await _userManager.GetUserAsync(User); PBEUser = await QuizUser.GetOrAddPBEUserAsync(_context, user.Email); if (!PBEUser.IsQuizModerator()) { return(RedirectToPage("/error", new { errorMessage = "Sorry! You do not have sufficient rights to edit a PBE BookList" })); } QuizBookList BookListToUpdate = await _context.QuizBookLists.FindAsync(Id); if (BookListToUpdate == null) { return(RedirectToPage("/error", new { errorMessage = "That's Odd! We weren't able to find this Book List" })); } await _context.Entry(BookListToUpdate).Collection(L => L.QuizBookListBookMaps).LoadAsync(); // We need a copy of the BookListMap to compare to while the origonal is being updated. List <QuizBookListBookMap> CompareMap = BookListToUpdate.QuizBookListBookMaps.ToList(); BibleId = await Bible.GetValidPBEBibleIdAsync(_context, BibleId); // Is this an attempted name change... for reals? if (Name.ToLower() != BookList.BookListName.ToLower()) { if (await QuizBookList.ListNameAlreadyExistsStaticAsync(_context, Name)) { ModelState.AddModelError("Name", "Sorry, this Name is already in use."); } // Update the name since this is a rename attempt. BookListToUpdate.BookListName = Name; } if (!ModelState.IsValid) { BookList.PadBookListBookMapsForEdit(); Books = BookList.QuizBookListBookMaps.ToList(); Name = BookList.BookListName; ViewData["BookSelectList"] = await BibleBook.GetBookSelectListAsync(_context, BibleId); return(Page()); } _context.Attach(BookListToUpdate); BookListToUpdate.Modified = DateTime.Now; // now we need to update the books foreach (QuizBookListBookMap Book in Books) { // See if this is one of our existing BookMaps bool ExistingBookMap = true; QuizBookListBookMap OriginalBook = new QuizBookListBookMap(); try { OriginalBook = CompareMap.Where(B => B.Id == Book.Id).Single(); } catch { ExistingBookMap = false; // New Book Scenario let's add the book. // But first we won't add it if the Book is already in the List. if (BookListToUpdate.QuizBookListBookMaps.Where(B => B.BookNumber == Book.BookNumber).Any()) { // Dupe scenario, don't add } else { if (Book.BookNumber > 0) { QuizBookListBookMap BookToAdd = new QuizBookListBookMap(); BookToAdd.BookList = BookListToUpdate; BookToAdd.IsDeleted = false; BookToAdd.Created = DateTime.Now; BookToAdd.Modified = DateTime.Now; BookToAdd.BookNumber = Book.BookNumber; _context.QuizBookListBookMaps.Add(BookToAdd); //await _context.SaveChangesAsync(); } } } if (ExistingBookMap) { // This is the update BookMap scenario if (OriginalBook.BookNumber != Book.BookNumber) { if (Book.BookNumber != 0) { _context.Attach(OriginalBook); OriginalBook.Modified = DateTime.Now; OriginalBook.BookNumber = Book.BookNumber; // await _context.SaveChangesAsync(); } else { // This is the delete BookMap scenario _context.QuizBookListBookMaps.Remove(OriginalBook); // await _context.SaveChangesAsync(); } } } } await _context.SaveChangesAsync(); return(RedirectToPage("BookLists", new { BibleId = this.BibleId, Message = String.Format("Book List {0} successfully updated...", BookListToUpdate.BookListName) })); }
public async Task <IActionResult> OnPostAsync(int?id, int spaces) { if (id == null) { return(RedirectToPage("/error", new { errorMessage = "Sorry! The Step Id cannot be null" })); } Step = await _context.PathNodes.FindAsync(id); if (Step == null) { return(RedirectToPage("/error", new { errorMessage = "That's Odd! We were not able to find this Step" })); } int StartPosition = Step.Position; int TempPosition = StartPosition; Path = await _context.Paths.FindAsync(Step.PathId); if (Path == null) { return(RedirectToPage("/error", new { errorMessage = "That's Odd! We weren't able to find this Path" })); } IdentityUser user = await _userManager.GetUserAsync(User); if (!Path.IsValidPathEditor(user.Email)) { return(RedirectToPage("/error", new { errorMessage = "Sorry! You do not have permissions to move this step." })); } if (spaces < 0) // this is the move up scenario { TempPosition = StartPosition + (10 * spaces) - 4; // the minus 4 pushes us above the target step, where want to be and won't conflict with add steps 5. if (TempPosition < 0) { TempPosition = 0; } } if (spaces > 0) // the move down scenario { TempPosition = StartPosition + (10 * spaces) + 3; // the plus 3 pushes us above the target step, where want to be and won't conflict with add steps 5. } // Move the step _context.Attach(Step).State = EntityState.Modified; Step.Modified = DateTime.Now; Step.Position = TempPosition; await _context.SaveChangesAsync(); // Register the event if (!Path.IsPathOwner(user.Email)) { _ = await Path.RegisterEventAsync(_context, EventType.NonOwnerEdit, user.Email); } // Update the Path modified date. _context.Attach(Path); Path.Modified = DateTime.Now; await _context.SaveChangesAsync(); // Finally we need to re-position each node in the path to ensure safe ordering _ = await Path.RedistributeStepsAsync(_context); return(RedirectToPage("/Paths/Steps", new { PathId = Step.PathId })); }
// To protect from overposting attacks, please enable the specific properties you want to bind to, for // more details see https://aka.ms/RazorPagesCRUD. public async Task <IActionResult> OnPostAsync() { if (!ModelState.IsValid) { // Setup our PBEBible Object Question.BibleId = await QuizQuestion.GetValidBibleIdAsync(_context, Question.BibleId); BibleBook PBEBook = await BibleBook.GetPBEBookAndChapterAsync(_context, Question.BibleId, Question.BookNumber, Question.Chapter); if (PBEBook == null) { return(RedirectToPage("/error", new { errorMessage = "That's Odd! We weren't able to find the PBE Book." })); } Question.PopulatePBEQuestionInfo(PBEBook); Question.Verses = await Question.GetBibleVersesAsync(_context, false); // We should still have AnswerText IsCommentary = (Question.Chapter == Bible.CommentaryChapter); if (IsCommentary == false) { ChapterQuestionCount = PBEBook.BibleChapters.Where(c => c.ChapterNumber == Question.Chapter).First().QuestionCount; } CommentaryQuestionCount = PBEBook.CommentaryQuestionCount; // and now we need a Verse and Points Select List ViewData["VerseSelectList"] = new SelectList(Question.Verses, "Verse", "Verse"); ViewData["PointsSelectList"] = Question.GetPointsSelectList(); return(Page()); } // confirm our user is a valid PBE User. IdentityUser user = await _userManager.GetUserAsync(User); PBEUser = await QuizUser.GetOrAddPBEUserAsync(_context, user.Email); if (!PBEUser.IsValidPBEQuestionBuilder()) { return(RedirectToPage("/error", new { errorMessage = "Sorry! You do not have sufficient rights to edit a PBE question" })); } // Now let's create an empty question and put only our validated properties onto it. QuizQuestion QuestionToUpdate = await _context.QuizQuestions.FindAsync(Question.Id); if (QuestionToUpdate == null) { return(RedirectToPage("/error", new { errorMessage = "That's Odd! We weren't able to find this Question" })); } if (await TryUpdateModelAsync <QuizQuestion>( QuestionToUpdate, "Question", // Prefix for form value. Q => Q.BibleId, Q => Q.Points, Q => Q.StartVerse, Q => Q.EndVerse, Q => Q.Question, Q => Q.Challenged, Q => Q.ChallengeComment)) { QuestionToUpdate.Modified = DateTime.Now; // now we need to add the Answer if there is one. if (AnswerText.Length > 0) { // We need the Original Answer and while techincally we support multiple Answers // we are only going to allow operating on the first one in this basic edit experience. await _context.Entry(QuestionToUpdate).Collection(Q => Q.QuizAnswers).LoadAsync(); if (QuestionToUpdate.QuizAnswers.Count > 0) { QuizAnswer OriginalAnswer = QuestionToUpdate.QuizAnswers.OrderBy(A => A.Id).First(); if (OriginalAnswer.Answer != AnswerText) { _context.Attach(OriginalAnswer); OriginalAnswer.Modified = DateTime.Now; OriginalAnswer.Answer = AnswerText; QuestionToUpdate.IsAnswered = true; } } } await _context.SaveChangesAsync(); switch (ReturnPath) { case "Questions": return(RedirectToPage("Questions", new { BibleId = QuestionToUpdate.BibleId, BookNumber = QuestionToUpdate.BookNumber, Chapter = QuestionToUpdate.Chapter })); // break; not needed unreachable case "ChallengedQuestions": return(RedirectToPage("ChallengedQuestions", new { BibleId = QuestionToUpdate.BibleId })); // break; not needed unreachable default: return(RedirectToPage("AddQuestion", new { BibleId = QuestionToUpdate.BibleId, BookNumber = QuestionToUpdate.BookNumber, Chapter = QuestionToUpdate.Chapter, VerseNum = QuestionToUpdate.EndVerse })); // break; not needed unreachable } } return(RedirectToPage("Index")); }
// To protect from overposting attacks, please enable the specific properties you want to bind to, for // more details see https://aka.ms/RazorPagesCRUD. public async Task <IActionResult> OnPostAsync(int Id) { IdentityUser user = await _userManager.GetUserAsync(User); PBEUser = await QuizUser.GetOrAddPBEUserAsync(_context, user.Email); PredefinedQuiz TemplateToUpdate = await _context.PredefinedQuizzes.FindAsync(Id); if (TemplateToUpdate == null) { return(RedirectToPage("/error", new { errorMessage = "Thats Odd! We were unable to find this Quiz Template" })); } if (!PBEUser.IsValidPBEQuestionBuilder() || PBEUser != TemplateToUpdate.QuizUser) { return(RedirectToPage("/error", new { errorMessage = "Sorry! You do not have sufficient rights to configure this Quiz Template" })); } if (TemplateToUpdate.QuizUser != PBEUser) { return(RedirectToPage("/error", new { errorMessage = "Sorry! Only a Template Owner may edit a Template" })); } this.BibleId = await Bible.GetValidPBEBibleIdAsync(_context, BibleId); _context.Entry(TemplateToUpdate).Collection(T => T.PredefinedQuizQuestions).Load(); // We need a copy of the Questions list to compare to while the origonal is being updated. List <PredefinedQuizQuestion> CompareQuestions = TemplateToUpdate.PredefinedQuizQuestions.ToList(); if (!ModelState.IsValid) { //Initialize Our Template Questions Questions = TemplateToUpdate.IntiQuestionListForAddEdit(); // Initialize Template Books TemplateBooks = await Template.GetTemplateBooksAsync(_context, this.BibleId); JSONBooks = JsonSerializer.Serialize(TemplateBooks); // Build Select Lists foreach (PredefinedQuizQuestion Question in Questions) { Question.AddChapterSelectList(TemplateBooks); } ViewData["BookSelectList"] = MinBook.GetMinBookSelectListFromList(TemplateBooks); return(Page()); } _context.Attach(TemplateToUpdate); TemplateToUpdate.Modified = DateTime.Now; // Iterate through each of our Questions and make appropriate changes. foreach (PredefinedQuizQuestion Question in Questions) { // See if this is one of our existing Question objects. bool ExistingQuestion = true; PredefinedQuizQuestion OriginalQuestion = new PredefinedQuizQuestion(); try { OriginalQuestion = CompareQuestions.Where(Q => Q.QuestionNumber == Question.QuestionNumber).Single(); } catch { ExistingQuestion = false; // New Question Scenario let's add the Question. if (Question.BookNumber != 0) { PredefinedQuizQuestion QuestionToAdd = new PredefinedQuizQuestion(); QuestionToAdd.PredefinedQuiz = TemplateToUpdate; QuestionToAdd.QuestionNumber = Question.QuestionNumber; QuestionToAdd.BookNumber = Question.BookNumber; QuestionToAdd.Chapter = Question.Chapter; _context.PredefinedQuizQuestions.Add(QuestionToAdd); } } if (ExistingQuestion) { // Do we need to update OriginalQuestion? if (OriginalQuestion.BookNumber != Question.BookNumber || OriginalQuestion.Chapter != Question.Chapter) { if (Question.BookNumber != 0) { // this is the update scenario _context.Attach(OriginalQuestion); OriginalQuestion.BookNumber = Question.BookNumber; OriginalQuestion.Chapter = Question.Chapter; } else { // this is the delete scenario _context.PredefinedQuizQuestions.Remove(OriginalQuestion); } } } await _context.SaveChangesAsync(); } return(RedirectToPage("./Quizzes", "", new { BibleId = this.BibleId, Message = String.Format("Quiz Template {0} configured successfuly.", TemplateToUpdate.QuizName) }, "Templates")); }