I have 2 models, one for Poll
and for PollOption
. In the create action, I want to add 1 Poll
to the database and a list of PollOptions
as well. Each PollOption
has a foreign key PollId
.
When I submit the form, the modelstate is never set to valid because the Id and ForeignId in the tables are always empty even though I put a hidden input in the HTML. So why is it happening?
Models:
public class Poll
{
[Key]
public int Id { get; set; }
[Required]
public string Question { get; set; } = "";
}
public class PollOption
{
[Key]
public int Id { get; set; }
[Required]
public string Option { get; set; } = "";
[Required]
public int PollId { get; set; }
[ForeignKey("PollId")]
[ValidateNever]
public Poll Poll { get; set; }
}
View model:
public class PollVM
{
public Poll Poll { get; set; }
[ValidateNever]
public List<PollOption> PollOptions { get; set; }
}
Action:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(PollVM pollVM) {
if(ModelState.IsValid)
{
pollVM.PollOptions.ForEach(p => p.Poll = pollVM.Poll);
_unitOfWork.PollOption.AddRange(pollVM.PollOptions);
_unitOfWork.Save();
return RedirectToAction("Index");
}
return View(pollVM);
}
View:
@model PollVM
<div class="index-container">
<div class="subcontainer">
<h1 class="title">Poll Creator</h1>
<h2 class="subtitle">Complete the form below to create your poll!</h2>
<form method="POST" asp-action="Create">
<input asp-for="Poll.Id" type="hidden" />
<div class="form-container">
<div class="form-input">
<label asp-for="Poll.Question">Question:</label>
<input asp-for="Poll.Question" type="text" placeholder="Type the poll question here" required>
</div>
<div class="form-input">
<div class="form-input form-options">
<label>Answer Options:</label>
<div class="form-option">
<input name="PollOptions[0].Id" type="hidden" />
<input name="PollOptions[0].PollId" type="hidden" />
<input name="PollOptions[0].Option" type="text" placeholder="Option 1" required>
<img src="~/images/icons/cross.svg" alt="remove-option" width="30px" class="remove-option" onclick="removeOption(this)">
</div>
<div class="form-option">
<input name="PollOptions[1].Id" type="hidden" />
<input name="PollOptions[1].PollId" type="hidden" />
<input name="PollOptions[1].Option" type="text" placeholder="Option 2" required>
<img src="~/images/icons/cross.svg" alt="remove-option" width="30px" class="remove-option" onclick="removeOption(this)">
</div>
</div>
<button type="button" class="button side-button icon-button">Add Option <img src="~/images/icons/plus.svg" alt="add-option" width="25px"></button>
</div>
<button type="submit" class="button submit-button">Create!</button>
</div>
</form>
</div>
</div>
@section Scripts {
<script src="~/js/answer-options.js" asp-append-version="true"></script>
}
2
Answers
You forget to fill the value for hidden input:
<input name="PollOptions[0].Id" value="@Model.PollOptions[0].Id" type="hidden"/>
I test it,
[ForeignKey()]
is not in correct place.you must use it above the
public int PollId { get; set; }
property