标题:ASP MVC上ViewModel字段的条件验证
我对ASP MVC验证有疑问。假设我有以下视图模型
public class PersonViewModel
{
[Required]
public string Name {get; set; }
[Required]
public string Email {get; set; }
}
根据这一点,当我提交表单时,MVC将验证两个字段都有值。但是,在我的网站中,我遇到了可以在全局站点设置中关闭电子邮件的情况,因此模型将仅在表单上呈现名称文本框。现在当我提交表单时,它仍然要求我输入电子邮件字段,因为它被指示为“必需”,尽管用户现在无法填写该字段。
使用ASP MVC验证时是否有针对此类场景的解决方案?
答案 0 :(得分:4)
解决方案是,您必须取消Required
字段上的Email
属性,并在帖子上自行执行验证,如果设置了此类设置。像这样的东西
[HttpPost]
public ActionResult Post(PersonViewModel model)
{
//replace EmailTurnedOff with your setting
if (!EmailTurnedOff && string.IsNullOrWhiteSpace(model.Email))
{
ModelState.AddModelError("Email", "Field is Required");
}
if (ModelState.IsValid)
{
//do whatever
}
return View(model);
}
答案 1 :(得分:4)
我似乎找到了解决方案:
if(EmailTurnedOff)
{
this.ViewData.ModelState.Remove("Email");
}
然后,当我调用ModelState.IsValid时,它会给我正确答案
答案 2 :(得分:0)
背驮groovejet,这就是我在Controller中使用条件[Required]而不是视图模型的方式。我之所以这样做,是因为我只想在我的应用程序中忽略[必需]的一个动作。
public ActionResult Update(MyViewModel mVM)
{
if(mVM.Role == "Role" && mVM.Property == null)
{
ModelState.Remove("Property");
}
if (ModelState.IsValid)
{
// code...
}
}
答案 3 :(得分:0)
可以从ViewModel执行条件验证。 ViewModel类将需要实现IValidatableObject接口。
然后在ViewModel的底部添加一个与此类似的方法:
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (validationContext == null)
return null;
var valResults = new List<ValidationResult>();
if (!EmailExists))
valResults.Add(new ValidationResult($"Email is required.", new[] { "EmailErrorMsg" }));
return valResults;
}
别忘了在视图的正确位置添加一个ValidationMessage:
@Html.ValidationMessage("EmailErrorMsg")
快乐编码!