当多个控件具有相同的名称时进行无提示验证



我在不引人注目的验证方面遇到了问题,因为我有一个控件集合,并且所有控件都有相同的名称。我将感谢任何意见,并将考虑完全不同的方法

我的控件需要相同的名称,因为它们与模型中的集合绑定,并且MVC4为此使用控件名称(这是有效的)。非侵入式验证根据名称查找控件,因此它总是查找最后一个。

以下是所有详细信息:

我的模型中有一组字符串。

public List<String> Signatures { get; set; }

字符串被绑定到视图中的一组文本框。文本框的数量基于单选按钮中的选择。如果他们选择0,则不显示任何内容,选择1,则显示一个内容,选择2,则显示2,最多显示三个内容。

我只在视图中放置了3个文本框,并使用客户端jQuery根据所选的单选按钮显示或隐藏。

在视图中,每个文本框都是一个与模型绑定的html Helper类。下面是一个有两个文本框的示例。(我在每个下手动添加验证跨度)

@Html.TextBoxFor(m => m.Signatures, new { @class = " firstSigLabel " })
<span class="field-validation-valid" data-valmsg-for="Signatures" data-valmsg-replace="true"></span>
@Html.TextBoxFor(m => m.Signatures, new { @class = " secondSigLabel})
<span class="field-validation-valid" data-valmsg-for="Signatures" data-valmsg-replace="true"></span>

单击save后,操作方法将两个textBox与Signatures集合正确绑定。

现在我需要添加验证,这取决于我实际显示的文本框(单选按钮中的数字)。我希望客户端能像让MVC处理一样工作(不引人注目的验证)。我们有一个库,它依赖于此执行一些常见任务(如显示指示器)。

当我显示一个文本框时,我使用jQuery添加不引人注目的验证所需的属性(并在隐藏时删除它们)。这样,如果显示它,则它是必需的,如果隐藏它,则不需要它。以下是可见的输入:

<input id="Signatures" class=" firstSigLabel" type="text" value="" name="Signatures"  data-val-required="Enter a first Signature Label." data-val="true"></input>
<input id="Signatures" class=" secondSigLabel" type="text" value="" name="Signatures" data-val-required="Enter a second Signature Label." data-val="true"></input>

我还使用不引人注目的验证重新注册了来自:

$(theForm).removeData('validator');
$.validator.unobtrusive.parse($(theForm));

我的问题是,不引人注目的验证使用SPAN中的'data-vanceg-for'属性,通过name查找元素。然而,我有两个输入的名字,它总是找到最后一个。

我尝试过更改ID(Signatures1,Signatures2),但没有任何作用。

我不知道如何更改html助手中的名称,但如果我这样做,就会破坏控制器中的模型绑定。

我知道这并不简单——这确实是一种突兀的验证。我不知道如何使用注释来实现这一点,因为它依赖于客户端操作。

我想,如果我在绑定到同一模型属性的三个文本框上使用ValidationMessageFor,我仍然会遇到这个问题。

有没有办法克服这个问题?

我是不是错过了什么?

你能想出更好的方法吗?

与其绑定到集合,不如绑定到集合中的元素。即使集合为空,这也会起作用。这里有一个例子:

@Html.TextBoxFor (m => m.Signatures[0], new { @class = "firstSigLabel" })
@Html.TextBoxFor (m => m.Signatures[0], new { @class = "firstSigLabel" })

当它被渲染时,它将看起来像这样(我只包含了相关的标记):

<input id="Signatures_0_" name="Signatures [0]"></input>
<input id="Signatures_1_" name="Signatures [1]"></input>

现在,每个控件都有一个不同的名称,不引人注目的验证应该可以工作。您可以将集合保留为List数据类型,因为它实现了ICollection。

如果将签名集合定义为

ICollection<String> Signatures

然后,当您引用视图中的字段时,您应该能够将它们引用为Signatures[0]、Signatures[1]等,并且模型绑定器将自动使用

ICollection<T>.Add

方法,以确保它们都正确地映射回集合。