В приведенном ниже коде все значения в QuestionViewModel
равны нулю. Есть идеи, что я делаю неправильно по поводу привязки?
файл cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Identity;
using VerityLearn.DataAccess;
using VerityLearn.Domain;
using VerityLearn.DataAccess.UOW;
using VerityLearn.WebUI.ViewModels;
namespace VerityLearn.WebUI.Pages.Questions
{
[Authorize]
public class StudentQuestionsModel : PageModel
{
private readonly SignInManager<VerityUser> _signInManager;
private readonly UserManager<VerityUser> _userManager;
private readonly IStudentQuesionsUOW _studentQuesionsUOW;
private readonly VerityLearn.DataAccess.VerityContext _context;
public StudentQuestionsModel(
VerityContext context,
SignInManager<VerityUser> signInManager,
UserManager<VerityUser> userMrg,
IStudentQuesionsUOW studentQuesionsUOW
)
{
_context = context;
_signInManager = signInManager;
_userManager = userMrg;
_studentQuesionsUOW = studentQuesionsUOW;
} // end public StudentQuestionsModel(VerityContext context, SignInManager<VerityUser> signInManager, UserManager<VerityUser> userMrg)
#region User Properties
public VerityUser VerityUser { get; set; }
//[TempData]
//public string UserId { get; set; }
public Student Student { get; set; }
public Prospect Prospect { get; set; }
public Parent Parent { get; set; }
public ExamUserViewModel ExamUserViewModel { get; set; }
#endregion // User Properties
public DateTime DateStarted { get; set; }
public Exam Exam { get; set; }
[TempData]
public int ExamId { get; set; }
ExamQuestion ExamQuestion { get; set; }
public List<ExamQuestion> ExamQuestions { get; set; }
[TempData]
public int NbrOfExamQuestions { get; set; }
public ExamViewModel ExamViewModel { get; set; }
[TempData]
public int QuestionNdx { get; set; }
[BindProperty]
public QuestionViewModel QuestionViewModel { get; set; }
[ViewData]
public string Message { get; set; }
[BindProperty]
public Question Question { get; set; }
public async Task OnGetAsync(int? examId, int? questionNdx)
{
Message = string.Empty;
if (_signInManager.IsSignedIn(HttpContext.User))
{
string email = HttpContext.User.Identity.Name;
VerityUser = await _studentQuesionsUOW.GetVerityUser(email);
//UserId = VerityUser.Id.ToString();
// TODO: Setup priorities of setting Student, Prospect and Parent properties, might involve Enrollments 4/30/2020
//Student = await _context.Students.Where(s => s.UserId == VerityUser.Id).FirstOrDefaultAsync<Student>();
//Prospect = await _context.Prospects.Where(p => p.UserId == VerityUser.Id).FirstOrDefaultAsync<Prospect>();
//Parent = await _context.Parents.Where(p => p.UserId == VerityUser.Id).FirstOrDefaultAsync<Parent>();
DateStarted = DateTime.Now;
if ((examId != null) && (examId.Value > 0))
{
ExamId = examId.Value;
Exam = await _context.Exams.Where(e => e.ExamId == examId)
.Include(e => e.Course).ThenInclude(c => c.Subject).FirstOrDefaultAsync<Exam>();
if (Exam != null)
{
ExamUserViewModel = new ExamUserViewModel
{
ExamUserId = 0,
ExamId = Exam.ExamId,
TimeStarted = DateTime.Now,
Status = ExamUserStatus.InProgress,
StudentId = VerityUser.StudentId,
ProspectId = VerityUser.ProspectId,
ParentId = VerityUser.ParentId
};
// TODO: If this is a new ExamUser, we must insert it to VerityLearnDB2.ExamUsers
if (NbrOfExamQuestions == 0)
{
ExamQuestions = await _context.ExamQuestions
.Where(eq => eq.ExamId == examId)
.ToListAsync<ExamQuestion>();
NbrOfExamQuestions = ExamQuestions.Count;
TempData.Keep("NbrOfExamQuestions");
} // endif (NbrOfExamQuestions == 0)
if ((questionNdx == null) || (questionNdx.Value == 0))
{
questionNdx = 1;
} // endif ((questionNdx == null) || (questionNdx.Value == 0))
QuestionNdx = questionNdx.Value;
TempData.Keep("QuestionNdx");
ExamQuestion = await _context.ExamQuestions
.Include(eq => eq.Question)
.ThenInclude(q => q.Options)
.Where(eq => eq.ExamQuestionOrder == questionNdx)
.FirstOrDefaultAsync<ExamQuestion>();
QuestionViewModel = new QuestionViewModel
{
QuestionId = ExamQuestion.QuestionId,
ExamQuestionOrder = ExamQuestion.ExamQuestionOrder,
QuestionText = ExamQuestion.Question.QuestionText,
IsSingleSelection = ExamQuestion.Question.IsSingleSelection,
Options = new List<OptionViewModel>()
};
ExamViewModel = new ExamViewModel
{
ExamId = Exam.ExamId,
ExamName = Exam.ExamName,
Questions = new List<QuestionViewModel>()
};
ExamViewModel.Questions.Add(QuestionViewModel);
ExamViewModel.ExamUserViewModel = ExamUserViewModel;
List<AnswerOption> answerOptions = _context.AnswerOptions
.Where(ao => ao.QuestionId == ExamQuestion.QuestionId)
.ToList<AnswerOption>();
foreach (AnswerOption ao in answerOptions)
{
OptionViewModel ovm = new OptionViewModel
{
OptionId = ao.OptionId,
OptionText = ao.OptionText,
IsCorrect = ao.IsCorrect
};
ovm.UserExamOptionViewModel = new UserExamOptionViewModel
{
UserExamOptionId = ExamUserViewModel.ExamUserId,
UserExamId = 0,
OptionId = ao.OptionId,
IsSelected = false
};
QuestionViewModel.Options.Add(ovm);
}
}
else
{
Message = String.Format("Error: Exam with Identifier, {0}, was not found.", examId);
}
}
else
{
Message = String.Format("Error: Exam with Identifier, {0}, was not found.", examId);
}
}
else
{
Message = "Error: Login is required.";
}
}
public async Task<IActionResult> OnPostAsync(QuestionViewModel QuestionViewModel)
{
var t = QuestionViewModel;
if (!ModelState.IsValid)
{
return Page();
}
_context.Attach(Question).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
}
return RedirectToPage("./Index");
}
}
}
cs html файл:
@page "{examId:int?}"
@model VerityLearn.WebUI.Pages.Questions.StudentQuestionsModel
@{
ViewData["Title"] = "StudentQuestions";
}
@if (String.IsNullOrEmpty(@Model.Message))
{
<div class="row" style="background-color: #5D2685; color: #FFFF80;">
<div class="col-md-6">
<h4>Exam: @Html.DisplayFor(model => model.Exam.ExamName)</h4>
</div>
<div class="col-md-6">
<h4>Course: @Html.DisplayFor(model => model.Exam.Course.CourseName)</h4>
</div>
</div>
<br />
<br />
<div>
<h4>Question</h4>
<hr />
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="Question.QuestionId" />
<div class="form-group">
<label asp-for="Question.QuestionText" class="control-label"></label>
<input asp-for="Question.QuestionText" class="form-control" />
<span asp-validation-for="Question.QuestionText" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Question.KeyToAnswer" class="control-label"></label>
<input asp-for="Question.KeyToAnswer" class="form-control" />
<span asp-validation-for="Question.KeyToAnswer" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Question.IsSingleSelection" class="control-label"></label>
<input asp-for="Question.IsSingleSelection" class="form-control" />
<span asp-validation-for="Question.IsSingleSelection" class="text-danger"></span>
</div>
<label asp-for="QuestionViewModel.QuestionText" class="control-label"></label>
@if (Model.QuestionViewModel.IsSingleSelection.Value)
{
<p>Select the correct option.</p>
@foreach (OptionViewModel opt in Model.QuestionViewModel.Options)
{
<input type="radio" name="option" value="@opt.UserExamOptionViewModel.IsSelected"><label for=" @opt.OptionText"> @opt.OptionText </label><br />
}
}
else
{
<p>Select the correct options (More than one).</p>
@foreach (OptionViewModel opt in Model.QuestionViewModel.Options)
{
<input type="checkbox" name="option" value="@opt.UserExamOptionViewModel.IsSelected"><label for=" @opt.OptionText"> @opt.OptionText </label><br />
}
}
@{
var prevDisabled = (Model.QuestionNdx <= 1) ? "disabled" : "";
var nextDisabled = (Model.QuestionNdx >= Model.NbrOfExamQuestions) ? "disabled" : "";
}
<button type="submit" asp-route-questionIndex="@(Model.QuestionNdx - 1)" class="btn btn-primary @prevDisabled">Previous</button>
<button type="submit" asp-route-questionIndex="@(Model.QuestionNdx + 1)" class="btn btn-primary @nextDisabled">Next</button>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
}
else
{
<div class="row" style="background-color: #5D2685; color: #FFFF80;">
<div class="col-md-6">
<h4>@Model.Message</h4>
</div>
</div>
}
ОБНОВЛЕНИЕ (5 / 11/2020):
Я упростил вид следующим образом:
@foreach(OptionViewModel opt in Model.QuestionViewModel.Options)
{
optionIndex++;
@Html.RadioButtonFor(model => model.QuestionViewModel.Options[optionIndex].OptionText, @opt.OptionText);
@opt.OptionText<br />
}
Я вижу 4 варианта, но все они выбраны. Я ожидаю, что будет выбран только один переключатель за раз. Я все равно нажимаю Далее
Теперь я вижу, что текст параметров привязан. Вопрос: Как определить, какой из них выбран?