mag*_*tte 2 asp.net asp.net-mvc-3
我正在使用编辑器模板和组合构建页面.我的视图模型包含自身视图模型的属性.例如
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; }
}
Run Code Online (Sandbox Code Playgroud)
我希望数据注释验证只有在父项的属性SomeCheckBox为true时才会启用子项.
我在stackoverflow上的其他地方看到过RequiredIf自定义验证属性,但只有在条件是相同视图模型的值时它才有效.我需要能够检查父母的东西,或者确实是祖先的财产.
我的临时黑客是如果复选框不为真,则清除回发时的ModelState错误.
我还必须编写一些自定义javascript,以便客户端浏览器在未勾选复选框时禁止验证.
真实的例子比这复杂得多,但希望从上面简化的例子可以清楚地知道我在追求什么.
什么是好的是父视图模型上的属性是类似的
public class ParentModel
{
public boolean SomeCheckBox { get; set; }
[SuppressValidationIf("SomeCheckBox", false)]
public ChildModel Child { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
这个优秀的例子完美地说明了进行声明性验证的局限性,这是数据注释的内容.
出于这个原因,我建议您使用命令式方法来处理验证规则,因为您可以处理许多场景.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);
}
}
Run Code Online (Sandbox Code Playgroud)
请注意如何根据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; }
}
Run Code Online (Sandbox Code Playgroud)
就这样.
您只需安装FluentValidation.MVC3NuGet,添加以下行Application_Start:
FluentValidationModelValidatorProvider.Configure();
Run Code Online (Sandbox Code Playgroud)
现在你像往常一样工作:
public class HomeController : Controller
{
public ActionResult Index()
{
return View(new ParentModel
{
Child = new ChildModel()
});
}
[HttpPost]
public ActionResult Index(ParentModel model)
{
return View(model);
}
}
Run Code Online (Sandbox Code Playgroud)
和一个观点:
@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>
}
Run Code Online (Sandbox Code Playgroud)
如果选中该复选框,子验证器将启动并要求2个属性.