我正在使用编辑器模板和合成构建一个页面。我的 View 模型包含本身就是 View 模型的属性。例如
public class ParentModel
{
public boolean SomeCheckBox { get; set; }
public ChildModel Child { get; set; }
}
public class ChildModel
{
[Required]
public string SomeString { get; set; }
[Required]
public string SomeOtherString { get; set; }
}
我希望仅当父项上的属性 SomeCheckBox 为真时,数据注释验证才会在子项上启动。
我在 stackoverflow 的其他地方看到了 RequiredIf 自定义验证属性,但它仅在条件是同一 View 模型的值时才有效。我需要一些可以检查父级的东西,或者实际上是祖先的属性。
我的临时 hack 是在复选框不正确时清除回发时的 ModelState 错误。
我还必须编写一些自定义 javascript,以便客户端浏览器在未勾选复选框时抑制验证。
实际示例比这复杂得多,但希望从上面的简化示例中可以清楚地看出我所追求的是什么。
如果父 View 模型上有一个类似这样的属性就好了
public class ParentModel
{
public boolean SomeCheckBox { get; set; }
[SuppressValidationIf("SomeCheckBox", false)]
public ChildModel Child { get; set; }
}
有什么想法吗?
最佳答案
这个出色的示例完美地说明了进行声明性验证的局限性,这就是数据注释。
出于这个原因,我建议您对验证规则使用命令式方法,因为您可以处理许多情况。 FluentValidation.NET是库的一个很好的例子,它可以使这个验证场景变得小菜一碟。
让我来说明它如何处理这种情况:
我们首先为子模型和父模型定义验证器:
public class ChildModelValidator : AbstractValidator<ChildModel>
{
public ChildModelValidator()
{
RuleFor(x => x.SomeString).NotEmpty();
RuleFor(x => x.SomeOtherString).NotEmpty();
}
}
public class ParentModelValidator : AbstractValidator<ParentModel>
{
public ParentModelValidator()
{
RuleFor(x => x.Child)
.SetValidator(new ChildModelValidator())
.When(x => x.SomeCheckBox);
}
}
注意子验证器是如何根据父验证器的 SomeCheckBox
属性值被包含进来的吗?现在你的模型看起来像这样:
[Validator(typeof(ParentModelValidator))]
public class ParentModel
{
public bool SomeCheckBox { get; set; }
public ChildModel Child { get; set; }
}
public class ChildModel
{
public string SomeString { get; set; }
public string SomeOtherString { get; set; }
}
仅此而已。
您只需安装 FluentValidation.MVC3
NuGet,在 Application_Start
中添加以下行:
FluentValidationModelValidatorProvider.Configure();
现在你照常工作了:
public class HomeController : Controller
{
public ActionResult Index()
{
return View(new ParentModel
{
Child = new ChildModel()
});
}
[HttpPost]
public ActionResult Index(ParentModel model)
{
return View(model);
}
}
和一个 View :
@model ParentModel
@Html.ValidationSummary(false)
@using (Html.BeginForm())
{
@Html.CheckBoxFor(x => x.SomeCheckBox)
@Html.EditorFor(x => x.Child.SomeString)
@Html.EditorFor(x => x.Child.SomeOtherString)
<button type="submit">OK</button>
}
如果复选框被选中,子验证器将启动并需要 2 个属性。
关于asp.net - 在父 View 模型的特定条件下,关闭本身是 View 模型的属性的数据注释验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8991526/