如何同时对多个对象进行验证并将其添加到部分视图

时间:2016-03-16 16:38:58

标签: c# asp.net-mvc validation

我正在为Parent实体开发一个表单,其中包含一个Child实体列表。

在Parent.cshtml中,我使用foreeach在局部视图中渲染子项:

@foreach (var child in Model.Children)
{
    Html.RenderPartial("_Child", child);
}

在_Child.cshtml中我使用此代码:

@using (Html.BeginCollectionItem("Children"))
{
    @Html.EditorFor(model => Model.ValidatedProperty, new {htmlAttributes = new {@class = "form-control"}})
    @Html.ValidationMessageFor(model => Model.ValidatedProperty, "", new {@class = "text-danger"})
}

当表单发回服务器时,我需要向Child.ValidatedProperty添加验证。 ValidatedProperty中的值必须按升序排序。 对于给定的Child实体,如果任何前面的Child实体在ValidatedProperty中具有更高的值,或者以下任何Child实体具有更低的值,则ValidatedProperty无效。

当我尝试实现这一点时,我遇到了以下问题:

当我尝试在控制器操作中验证并使用

ModelState.AddModelError("Parent.Children.Child[" + i + "].ValidatedProperty", "Please enter a value between " + prev + " and " + next);

消息未出现在屏幕上。

当我尝试创建ValidationAttribute或使用IValidatableObject接口时,我无法访问前面和后面的Child实体,因此我无法从那里进行验证。

当我查看源代码时,我的ValidationMessage html节点具有以下标记:

<span class="field-validation-valid" data-valmsg-replace="true" data-valmsg-for="Children[533f90da-4c11-40ca-bb07-e3f6bcbd7260].ValidatedProperty"></span>

非常欢迎所有建议! 如果我需要提供更多信息,请告诉我您需要了解的内容。 谢谢!

P.S。这是我正在尝试做的简化版本,真正的验证比检查正确的顺序要复杂一点。

编辑: 似乎对Html.BeginCollection的调用是将Children [533f90da-4c11-40ca-bb07-e3f6bcbd7260]部分添加到验证元素的名称中。当我删除BeginCollection语句时,它出现为:

<span class="field-validation-valid" data-valmsg-replace="true" data-valmsg-for="ValidatedProperty"></span>

不幸的是,我需要BeginCollection语句来实现页面的其他功能。有没有办法让验证消息与BeginCollection一起使用?

解决:

当我使用类似teo van kot的EditorTemplate建议我可以删除BeginCollectionItem语句,并且每个Child现在都以数字而不是guid作为前缀。现在我的AddModelError语句正常工作。

2 个答案:

答案 0 :(得分:2)

我不确定,但我猜你用Html.RenderPartial()打破了绑定,这就是为什么当你用ModelState.AddModelError()添加错误时它没有出现的原因。

我建议您使用EditorTemplate代替Html.RenderPartial()

您应该在EditorTemplates中创建文件夹Views\Shared,并为Model.Children属性 创建强类型视图,其名称与您的Children属性相同类型有

基本上,它与现在您在_Child名称下的视图相同。

然后改变:

@foreach (var child in Model.Children)
{
    Html.RenderPartial("_Child", child);
}

要:

@Html.EditorFor(x => x.Children)

请注意,您不需要设置模型IEnumerable<YourType>List<YourType>,因为即使您传递集合,EditorTemplates也能正常工作。

现在所有绑定都没问题。您可以使用 F12 键在浏览器中进行检查,并检查您的ValidatedProperty input name属性。然后,您就可以使用ModelState.AddModelError()方法。

答案 1 :(得分:1)

根据索引评估集合,但您需要在模型中引用集合名称。基于标记的ValidationMessage,模型状态错误必须为:

ModelState.AddModelError("Parent[" + i + "].ValidatedProperty", "Please enter a value between " + prev + " and " + next);