客户端验证未针对CompareAttribute DataAnnotation触发

bea*_*ous 5 data-annotations asp.net-mvc-3

我正在布局一个比较两个密码字符串的视图.我的一个模型中的两个属性非常简单:

    [Required]
    [RegularExpression(@"(\S)+", ErrorMessage = "White space is not allowed")]
    [StringLength(20, MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "New Password")]
    public string NewPassword { get; set; }

    [Required]
    [DataType(DataType.Password)]
    [RegularExpression(@"(\S)+", ErrorMessage = "White space is not allowed")]
    [StringLength(20, MinimumLength = 6)]
    [Display(Name = "Confirm Password")]
    [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }
Run Code Online (Sandbox Code Playgroud)

这是我的观看代码:

<table class="fieldset center" width="400">
    <tbody>
        <tr>
            <th width="150">
                @Html.LabelFor(m => m.NewPassword)
            </th>
            <td>
                @Html.PasswordFor(m => m.NewPassword, new { @class = "itext3" })
                <br /><br />@Html.ValidationMessageFor(m => m.NewPassword)
            </td>
        </tr>                       
        <tr>
            <th width="150">
                @Html.LabelFor(m => m.ConfirmPassword)
            </th>
            <td>
                @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "itext3" })
                <br /><br />@Html.ValidationMessageFor(m => m.ConfirmPassword)
            </td>
        </tr>
    </tbody>
</table>
Run Code Online (Sandbox Code Playgroud)

测试时,所有属性都会触发客户端验证消息,但ConfirmPassword上的CompareAttribute除外,直到我点击服务器才触发.但是,在我的控制器中,ModelState.IsValid = false.

我将我正在做的事情与正常工作的默认MVC应用程序进行了比较.有关故障排除和修复的建议吗?

我正在使用MVC 3 RTM.

Mar*_*iro 8

jquery.validate.unobtrusive.js(和jquery.validate.unobtrusive.min.js,缩小版本)中有一个BUG.如果compare-to字段是表单上的FIRST字段,那么作为[Compare]属性的结果发出的客户端验证将起作用.要修复此错误,请在jquery.validate.unobtrusive.js中找到此行:

element = $(options.form).find(":input[name=" + fullOtherName + "]")[0];
Run Code Online (Sandbox Code Playgroud)

这导致了这个等价物:

element = $(options.form).find(":input[name=MyExample.Control]")[0];
Run Code Online (Sandbox Code Playgroud)

不幸的是,这不是find()的正确语法,并导致它引用表单上的第一个输入控件.

将该行更改为:

element = $(options.form).find(":input[name='" + fullOtherName + "']")[0];
Run Code Online (Sandbox Code Playgroud)

这导致了这个等价物:

element = $(options.form).find(":input[name='MyExample.Control]'")[0];
Run Code Online (Sandbox Code Playgroud)

哪个是正确的语法,并正确匹配输入控件与指定的名称.

在jquery.validate.unobtrusive.min.js中找到相同的代码块,如下所示:

f=a(b.form).find(":input[name="+d+"]")[0];
Run Code Online (Sandbox Code Playgroud)

并将其更改为:

f=a(b.form).find(":input[name='"+d+"']")[0];
Run Code Online (Sandbox Code Playgroud)


Pim*_*nes 4

查看 _Layout.cshtml 中的脚本标记。我猜问题可能是你的 jQuery 引用。您是从头开始 MVC 3 项目还是使用示例项目或类似项目?

这就是我身上发生的事情;我也有类似的问题...

  • 我使用了一些在 src 属性中指向 ajax.microsoft.com 的示例代码
  • 因此,例如脚本标签之一如下所示:<script src="http://ajax.microsoft.com/ajax/jquery.validate/1.7/jquery.validate.min.js"></script>
  • 我想更好地处理 js 在客户端执行的内容,所以我将其更改为:<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
  • 这只是一个例子,我认为我还更改了更多脚本标签

因此,在更改为内部提供的 jQuery 文件后,它就可以工作了。我回去查看了本地 .validate.js 文件...它是 1.6 版本。这就是我意识到问题是由于 jQuery 的版本或其与其他 js 库之一的兼容性造成的。

最重要的是,它看起来 1.7 不能完全与我拥有的 validate.unobtrusive.js 库一起运行...可能有一个更新的版本可以与 1.7 一起运行...就像我说的,我正在修改一个示例项目,因此存在一些未知数。我想它也可能是它与其他 js 库之一之间的 MvcValidation.js 库不兼容?

无论如何,我想说陈述你的问题的最简单方法是你很可能引用了错误的 js 库组合。我想说获得 js 库的良好组合的最佳故障安全方法是在 Visual Studio 中创建一个新的 Asp.Net MVC 3 项目,并查看它默认/使用项目模板为您提供的版本......这是假设你不是从头开始这个项目的。如果您确实从头开始,那么您可能更改了布局文件以包含错误的 js 引用,或者如果这些都不是真的,那么我认为这可能是 VisualStudio 项目模板的问题?...实际上我想说的是虽然值得怀疑。所有这些都说明了 - 我想说最可能的原因 [无论如何我打赌] 是你像我一样遇到了麻烦,试图快速使用一些示例代码 =)