Hi guys,
As some of you knows, I'm developing a quiz application. I have timer in question view and this time I need to get the time between opening the question view and submitting the answer. Then I substruct that interval from 60 in order to get remained seconds which will be the point of the question if the answer is right. Here is the details:
View
@model Intellect.Models.ViewModels.AdminViewModel<div class="questioncontainer"> <form asp-action="Question" asp-controller="Home" asp-route-id="@Model.NextQuestion.Id" asp-route-count="@ViewBag.Equestions"><div class="row"><div class="col-lg-3"></div><div class="col-lg-6 col-sm-12"><table><tr><th>Qaliq vaxt</th></tr><tr><td><div id="time"></div> </td></tr></table><div class="question">@Model.CurrentQuestion.Description </div></div><div class="col-lg-3"></div></div><div class="row"><div class="col-lg-3 col-sm-0"></div> @{ int n = 0; } @foreach (Answer item in Model.Answers) { if (n == 0 || n == 2) { @: <div class="col-lg-3 col-sm-12"> @: <div class="firstpart"> }<input asp-for="@item.Id" name="@item.Id" hidden /><input type="radio" asp-for="@item.Id" name="myanswer" value="@item.Id" />@item.Description<br> if (n == 1 || n == 3) { @:</div> @:</div> } n++; }<div class="col-lg-3"></div></div><div class="row"><div class="col-lg-6 col-sm-4"></div><div class="col-lg-3 col-sm-4"></div><div class="col-lg-3 col-sm-4"><div class="nextbtn"> @if (ViewBag.Equestions == 0) {<input type="submit" value="Finish" /> } else {<input type="submit" value="Next" /> }</div></div></div></form></div> @section Script{ <script> function StartTimer(seconds) { var intSeconds = seconds; var timer = setInterval(myTimer, 1000); function myTimer() { if (intSeconds < 0) { Alert("bitdi") clearInterval(timer) return; } document.getElementById("time").innerText = intSeconds; intSeconds--; } } StartTimer(60);</script> }
Controller
public class HomeController : Controller { private readonly IntellectDbContext _intellectDbContext; private readonly UserManager<ExamUser> _userManager; private readonly SignInManager<ExamUser> _signInManager; static int exam_id = 0; static int? PreviousId = 0; static int result = 0; static int correctAnswer = 0; static List<Question> RemainedQuestions = new List<Question>(); static List<int> trueAnswers = new List<int>(); public HomeController(IntellectDbContext intellectDbContext, UserManager<ExamUser> userManager, SignInManager<ExamUser> signInManager) { _intellectDbContext = intellectDbContext; _userManager = userManager; _signInManager = signInManager; } [HttpGet] public async Task<IActionResult> Test(int Id) { exam_id = Id; AdminViewModel admodel = new AdminViewModel(); admodel.Equestions = await _intellectDbContext.Questions.Include(q => q.Answers).Where(q => q.ExamId == Id).ToListAsync(); admodel.CurrentQuestion = await _intellectDbContext.Questions.Where(q => q.ExamId == Id).FirstOrDefaultAsync(); RemainedQuestions = admodel.Equestions; PreviousId = admodel.CurrentQuestion.Id; return View(admodel); } [HttpGet] public async Task<IActionResult> Question(int Id, int count) { AdminViewModel admodel = new AdminViewModel(); admodel.CurrentQuestion = await _intellectDbContext.Questions.Where(x => x.Id == Id).SingleOrDefaultAsync(); admodel.Answers = await _intellectDbContext.Answers.Where(y => y.QuestionId == Id).ToListAsync(); admodel.Equestions = await _intellectDbContext.Questions.Where(q => q.ExamId == exam_id).ToListAsync(); // admodel.CurrentQuestion.Remainedtime = new TimeSpan(0, 0, 60); HttpContext.Session.SetString("currentQuestion_" + admodel.CurrentQuestion.Id, DateTime.Now.ToString()); if (count > 1) { var question = RemainedQuestions.Single(r => r.Id == admodel.CurrentQuestion.Id); PreviousId = question.Id; RemainedQuestions.Remove(question); admodel.NextQuestion = RemainedQuestions[0]; count -= 1; } else { admodel.NextQuestion = RemainedQuestions[0]; count -= 1; } if (count == -1) { return RedirectToAction(nameof(Finish)); } ViewBag.Equestions = count; return View(admodel); } [HttpPost] public async Task<IActionResult> Question(int Id, int count, int myanswer) { AdminViewModel admodel = new AdminViewModel(); admodel.CurrentQuestion = await _intellectDbContext.Questions.Where(x => x.Id == Id).SingleOrDefaultAsync(); admodel.Answers = await _intellectDbContext.Answers.Where(y => y.QuestionId == Id).ToListAsync(); admodel.Equestions = await _intellectDbContext.Questions.Where(q => q.ExamId == exam_id).ToListAsync(); // admodel.CurrentQuestion.Remainedtime = new TimeSpan(0, 0, 60); // HttpContext.Session.SetString("currentQuestion_" + admodel.CurrentQuestion.Id, DateTime.Now.ToString()); var interval = DateTime.Now - DateTime.Parse(HttpContext.Session.GetString("currentQuestion_" + Id)); correctAnswer = _intellectDbContext.Answers.Where(a => a.QuestionId == PreviousId && a.Correct == true).SingleOrDefault().Id; if (_signInManager.IsSignedIn(User)) { ExamUser examTaker = await _userManager.GetUserAsync(HttpContext.User); examTaker.TestTaker = await _intellectDbContext.TestTakers .Include(tt => tt.UserQuestions) .Where(t => t.Id == examTaker.TestTakerId) .FirstOrDefaultAsync(); admodel.CurrentQuestion = examTaker.TestTaker.UserQuestions.Select(u => u.Question).Where(x => x.Id == Id).SingleOrDefault(); if (myanswer == correctAnswer) { admodel.CurrentQuestion.Score = 60 - (int)interval.TotalMilliseconds / 1000; await _intellectDbContext.SaveChangesAsync(); // admodel.CurrentQuestion.Score = result; } } if (count > 1) { var question = RemainedQuestions.Single(r => r.Id == admodel.CurrentQuestion.Id); PreviousId = question.Id; RemainedQuestions.Remove(question); admodel.NextQuestion = RemainedQuestions[0]; count -= 1; } else { admodel.NextQuestion = RemainedQuestions[0]; count -= 1; } if(count == -1) { return RedirectToAction(nameof(Finish)); } ViewBag.Equestions = count; return RedirectToAction(nameof(Question)); } }
When I run the application, the following errors comes (refer to link) when clicking on Next to get to the next question view: https://prnt.sc/s6y9vy
As you see, action (Question) in controller cannot get string data from session to parse it.
The problem lies here: var interval = DateTime.Now - DateTime.Parse(HttpContext.Session.GetString("currentQuestion_" + Id));
Please, assist in solving this issue.