My PageModel is allowing users to submit the form multiple times. I’ve managed to replicate the behavior by using Space
to “click” the Save button multiple times.
I had implemented an overlay that prevents actively clicking on the button, but this circumvents the overlay.
Additionally, I disabled the save button:
<form id="questionnaireForm" method="post" onsubmit="disableSave(); toggleOverlay();">
<script>
function disableSave()
{
document.querySelector("#saveSectionButton").disabled = true
}
function toggleOverlay() {
const overlay = document.querySelector("#overlay")
var isHidden = overlay.classList.contains("d-none")
if (!isHidden) {
overlay.classList.add("d-none")
} else {
overlay.classList.remove("d-none")
}
}
</script>
This didn’t seem to be effective either.
I thought model binding was supposed to prevent this sort of thing from happening…
Still, I did add in a check that updates existing data instead of saving duplicate data in my OnPostAsync
method.
The method does a lot of work which isn’t strictly speaking relevant to my question, but ultimately it just goes ahead and saves the answer to the database if all the validations and whatever else passes.
public async Task<IActionResult> OnPostAsync()
{
// Work on the page modifies the public Answers BindProperty.
if (this.Answers == null || this.Answers.Count == 0)
{
throw new ArgumentException("Answers cannot be null or empty.");
}
var answered = this.Answers.Where(x => x.Value is not null);
foreach (var answer in answered)
{
// Basic validation removed for brevity.
var question = await context.QuestionnaireQuestions
.SingleOrDefaultAsync(x => x.Id == answer.QuestionId);
// Handle potential updates to the answer.
var existing = context.QuestionnaireAnswers
.Where(x => x.Question.Id == answer.QuestionId && x.Booking.Id == this.BookingId);
if (existing.Any())
{
await UpdateAnswer(this.BookingId, answer, question, existing);
continue;
}
// Continue to process and save the new answer to the database.
}
}
The obvious flaw here is that if multiple requests are submitted quickly as in my replication, then the first won’t have been saved yet before the 2nd starts evaluating for existing answers.
So how do I prevent the saving of multiple rows of identical data?