[タイトルには「質問ごとに 1 つのチェックボックスを選択する必要があります」と記載する必要がありますが、SO ではタイトルに「質問」という単語を使用できません]
簡単なQ/Aフォーム。1 つの例では、7 つの質問があります。POST で、私のコントローラー アクションはIEnumerable<AssessmentQuestionsModel>
. 私のAssessmentQuestionsModel
実装IValidatableObject
、および私の Validate メソッドは次のとおりです。
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (this.assessmentAnswers.Where(e => e.userAnswer == true).Count() == 0)
{
yield return new ValidationResult("You must select at least one answer for every question");
yield break;
}
}
これはビュー レベルで正常に機能しています。エラー メッセージが返され、検証の概要に表示されます。問題は、質問ごとに 1 つずつ、7 回返されることです。今のところ、jQuery を使用して検証サマリー UL を評価し、重複を削除していますが、それはハックのようです。私は何を間違っていますか?
ありがとう
[編集 - 検証結果のオーバーロードのテスト]
以下は、実際には 2 回呼び出されます。ただし、それらはグループ化されておらず、複数の検証エラーが引き続き表示されます。
if (this.assessmentAnswers.Where(e => e.UserAnswer== true).Count() == 0)
{
yield return new ValidationResult("You must select at least one answer for every question", new List<string>() { "NoAnswerMarked" });
yield break;
}
[編集 - 情報を見る]
@using System.Linq
@using System.Collections.Generic
@model IList<Academy.AssessmentQuestionsModel>
@{
ViewBag.Title = "TakeAssessment";
ViewBag.PageID = "TakeAssessment";
}
@section TitleBar {
<span>
@if(ViewBag.Status == "questions") {
<text>Take Assessment</text>
} else {
<text>Assessment Response</text>
}
</span>
}
@section JS {
<script type="text/javascript">
$(function () {
if ($(".validation-summary-errors li:contains('You must select at least one answer for every question')").length > 0) {
$(".validation-summary-errors ul")
.find("li:contains('You must select at least one answer for every question')")
.remove()
.end()
.append("<li>You must select at least one answer for every question</li>");
}
$("#asubmit").click(function (e) {
var hasErrors = false;
$(".newAnswerWrapper").each(function () {
if ($(this).find('input[type="checkbox"]:visible:checked').length == 0) {
e.preventDefault();
hasErrors = true;
return false;
}
});
if (hasErrors) {
$(".validation-summary-valid").find("ul").append("<li>You must select at least one answer for every question</li>").end().show();
} else {
$(".validation-summary-errors").find("li:contains('You must select at least one answer for every question'')").remove().end().hide();
}
});
});
</script>
}
@using (Html.BeginForm())
{
@Html.ValidationSummary(false)
<fieldset>
<legend></legend>
<div class="takeAssessment">
@if(!string.IsNullOrEmpty(ViewBag.AssessmentInstructions)) {
<h4>Instructions</h4>
<p>@ViewBag.AssessmentInstructions</p>
}
@{
int questionCount = 0;
int totalQuestions = Model.Count();
@Html.Hidden("ModuleID", (int)ViewBag.ModuleID)
for (var i = 0; i < Model.Count; i++)
{
@Html.HiddenFor(m => m[i].questionDescription)
<div class="newQuestionWrapper">
<h4>Question @(i + 1) of @totalQuestions</h4>
@Html.HiddenFor(m => m[i].assessmentID)
@Html.HiddenFor(m => m[i].assessmentQuestionID)
<p class="questionDescription">@Model[i].questionDescription</p>
<div class="newAnswerWrapper"></div>
<div class="newAnswerWrapper">
<div class="answerHeader">
<p class="correct">Select</p><p class="answers">Answer(s)</p>
</div>
@for (var j = 0; j < Model[i].assessmentAnswers.Count(); j++)
{
@Html.HiddenFor(m => m[i].assessmentAnswers[j].assessmentAnswerID)
@Html.HiddenFor(m => m[i].assessmentAnswers[j].assessmentQuestionID)
@Html.HiddenFor(m => m[i].assessmentAnswers[j].assessmentAnswer)
if (ViewBag.Status == "questions")
{
<div class="answerRow">
<span class="isAnswer first">@Html.CheckBoxFor(m => m[i].assessmentAnswers[j].userAnswer)</span>
<span class="answerDisplay">@Html.DisplayFor(m => m[i].assessmentAnswers[j].assessmentAnswer)</span>
@Html.HiddenFor(m => m[i].assessmentAnswers[j].isAnswer)
<div class="clear"></div>
</div>
}
else
{
<div class="answerRow">
@{
string cls = Model[i].assessmentAnswers[j].isAnswer ? "correct" : "incorrect";
}
<span class="isAnswer first">@Html.CheckBoxFor(m => m[i].assessmentAnswers[j].userAnswer, new { @disabled = "disabled" })</span>
<span class="answerDisplay" style="width: 510px !important;">@Html.DisplayFor(m => m[i].assessmentAnswers[j].assessmentAnswer)</span>
<span class="isAnswer"><span class="@cls">@Html.DisplayFor(m => m[i].assessmentAnswers[j].isAnswer)</span></span>
<div class="clear"></div>
</div>
}
<div class="clear"></div>
}
</div>
<div class="clear"></div>
</div>
}
}
<div class="clear"></div>
</div>
@if (ViewBag.Status == "questions")
{
<input type="submit" id="submit" value="Submit Assessment" class="redButton197x38" />
}
</fieldset>
}
<p>
@Html.ActionLink("Back to Module", "Learn", new { id = ViewBag.ModuleID }, new { @class = "redButton197x38" })
</p>