[英]Missing form validation in MVC application
我有一个只包含复选框的表单,我知道我可以使每一个都需要强制执行验证错误。 但是,如果没有选中任何一个方框,我正在寻找的是一个错误。 我将如何实现这一目标?
我正在寻找一条错误消息,例如:“您必须至少选择一个属性。”
我应该澄清,没有一个字段是单独需要的,应该至少有一个选择的选项。
编辑以澄清:
我的观点看起来像这样:
@using (Html.BeginForm("Method", "Controller", FormMethod.Post, new {id = "id"}))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.Property1, htmlAttributes: new { @class = "control-label col-md-4" })
<div class="col-md-8">
@Html.CheckBoxFor(model => model.Property1)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Property2, htmlAttributes: new { @class = "control-label col-md-4" })
<div class="col-md-8">
@Html.CheckBoxFor(model => model.Property2)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Property3, htmlAttributes: new { @class = "control-label col-md-4" })
<div class="col-md-8">
@Html.CheckBoxFor(model => model.Property3)
</div>
</div>
}
我的View模型看起来像这样:
public class FormVM
{
[Display(Name = "One")]
public bool Property1 {get;set;}
[Display(Name = "Two")]
public bool Property2 {get;set;}
[Display(Name = "Three")]
public bool Property3 {get;set;}
}
如果仅在一个地方使用此验证,则可以在Action方法中对其进行验证:
[HttpPost]
public ActionResult MyAction(FormVM model)
{
if (!(model.Property1 || model.Property2 || model.Property3))
{
ModelState.AddModelError(nameof(model.Property1), "You must select at least one");
}
if (ModelState.IsValid)
{
// Do something
}
return View(model);
}
如果您可能会更多地重复使用此验证,我建议您编写验证属性。
由于问题没有提到最好使用哪种服务器端或客户端验证,因此有两种方法。
1)服务器端验证(没有ModelState.AddModelError):
Controller.cs
[HttpPost]
public ActionResult Method(FormVM model)
{
if (ModelState.IsValid)
{
// ... other processing code and action returns
}
if (!(model.Property1 || model.Property2 || model.Property3))
{
ViewData["Error"] = "You must select at least one property." // this can be changed with ViewBag
// immediately return the same page
return View(model);
}
}
View.cshtml:
<p>@ViewData["Error"]</p>
2)使用vanilla JS进行客户端验证,使用id识别所需元素:
<script type="text/javascript">
var check1 = document.getElementById("check1").value;
var check2 = document.getElementById("check2").value;
var check3 = document.getElementById("check3").value;
if (!(check1 || check2 || check3))
{
document.getElementById("error").innerHTML = "You must select at least one property.";
}
else
{
document.getElementById("error").innerHTML = '';
}
</script>
<div class="form-group">
@Html.LabelFor(model => model.Property1, htmlAttributes: new { @class = "control-label col-md-4" })
<div class="col-md-8">
@Html.CheckBoxFor(model => model.Property1, htmlAttributes: new { @id = "check1" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Property2, htmlAttributes: new { @class = "control-label col-md-4" })
<div class="col-md-8">
@Html.CheckBoxFor(model => model.Property2, htmlAttributes: new { @id = "check2" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Property3, htmlAttributes: new { @class = "control-label col-md-4" })
<div class="col-md-8">
@Html.CheckBoxFor(model => model.Property3, htmlAttributes: new { @id = "check3" })
</div>
</div>
</div>
<div id="error"></div>
您可以在viewmodel上实现IValidatableObject
接口:
public class FormVM : IValidatableObject
{
[Display(Name = "One")]
public bool Property1 {get;set;}
[Display(Name = "Two")]
public bool Property2 {get;set;}
[Display(Name = "Three")]
public bool Property3 {get;set;}
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var results = new List<ValidationResult>();
if (!(Property1 || Property2 || Property3))
{
results.Add(new ValidationResult("You must select at least one property."));
}
return results;
}
}
使用它的好处是,如果在控制器中调用ModelState.IsValid
,则会自动触发,并且错误消息会添加到ModelState
错误中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.