Mar*_*nHN 7 jquery jquery-validate asp.net-mvc-3
升级到JQuery 1.5及更高版本1.5.1后,我的比较验证失败.我正在使用JQuery.Validate 1.7.我的ViewModel具有以下数据注释:
/// <summary>
/// Gets or sets the full name.
/// </summary>
/// <value>The full name.</value>
[Required]
[Display(Name = "fullname", ResourceType = typeof(Milkshake.Commerce.Model.Resources.Text))]
public string FullName { get; set; }
/// <summary>
/// Gets or sets the email.
/// </summary>
/// <value>The email.</value>
[DataType(DataType.EmailAddress)]
[Display(Name = "email", ResourceType = typeof(Milkshake.Commerce.Model.Resources.Text))]
[Required(ErrorMessageResourceName = "EmailRequired", ErrorMessageResourceType = typeof(Milkshake.Commerce.Model.Resources.ValidationMessages))]
[RegularExpression(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*", ErrorMessageResourceType = typeof(Milkshake.Commerce.Model.Resources.ValidationMessages), ErrorMessageResourceName = "EmailInvalid")]
public string Email { get; set; }
/// <summary>
/// Gets or sets the password.
/// </summary>
/// <value>The password.</value>
[DataType(DataType.Password)]
[Display(Name = "password", ResourceType = typeof(Milkshake.Commerce.Model.Resources.Text))]
[Required(ErrorMessageResourceName = "PasswordRequired", ErrorMessageResourceType = typeof(Milkshake.Commerce.Model.Resources.ValidationMessages))]
[ValidatePasswordLengthAttribute(ErrorMessageResourceName = "PasswordLength", ErrorMessageResourceType = typeof(Milkshake.Commerce.Model.Resources.ValidationMessages))]
public string Password { get; set; }
/// <summary>
/// Gets or sets the confirm password.
/// </summary>
/// <value>The confirm password.</value>
[DataType(DataType.Password)]
[Display(Name = "confirmPassword", ResourceType = typeof(Milkshake.Commerce.Model.Resources.Text))]
[Required(ErrorMessageResourceName = "PasswordRequired", ErrorMessageResourceType = typeof(Milkshake.Commerce.Model.Resources.ValidationMessages))]
[Compare("Password", ErrorMessageResourceName = "PasswordsMustMatch", ErrorMessageResourceType = typeof(Milkshake.Commerce.Model.Resources.ValidationMessages))]
public string ConfirmPassword { get; set; }
Run Code Online (Sandbox Code Playgroud)
我输入什么值,密码字段永远不会相同.
更新 - ASP.NET AntiForgeryToken遇到麻烦.
在FireBug设置断点中鬼混之后,我注意到在equalTo验证函数中,从jquery.validate.js中的第1065行开始,找到的目标元素不是Password字段 - 但__RequestVerificationTokenASP.NET MVC在写入时你使用Html.AntiForgeryToken()帮手.
这意味着我们甚至没有比较正确的输入元素.为了解决这个问题,我在jquery.validate.js文件中添加了一个脏的黑客:
// http://docs.jquery.com/Plugins/Validation/Methods/equalTo
equalTo: function (value, element, param) {
// bind to the blur event of the target in order to revalidate whenever the target field is updated
// TODO find a way to bind the event just once, avoiding the unbind-rebind overhead
var target = $(param).unbind(".validate-equalTo").bind("blur.validate-equalTo", function () {
$(element).valid();
});
if ($(target).is("input[type=hidden]") && $(target).attr("name") == "__RequestVerificationToken") {
var otherElementId = $(element).attr("id");
var underScoreIndex = otherElementId.indexOf("_");
otherElementId = otherElementId.substring(0, underScoreIndex + 1);
otherElementId += $(element).attr("data-val-equalto-other").substring(2);
target = $("#" + otherElementId);
}
return value == target.val();
}
Run Code Online (Sandbox Code Playgroud)
这个hack采用data-val-equalto-other属性的值,并将其与自己的ID混合,以找到正确的输入元素.在所有情况下都不会起作用.但在上述情况下,对我有用.
Dan*_*orf 11
我发现这是由于jquery.validate.unobtrusive.js中的错误
Unobtrusive中的代码添加了一个等于适配器,它尝试使用以下代码通过其name属性查找匹配元素:
element = $(options.form).find(":input[name=" + fullOtherName + "]")[0];
Run Code Online (Sandbox Code Playgroud)
fullOtherName变量通常(并且可能总是)用句点命名空间,因此jQuery选择器返回太多输入,并选择第一个.这段时间需要使用.replace(".","\\.")进行转义,为您提供:
element = $(options.form).find(":input[name=" + fullOtherName.replace(".", "\\.") + "]")[0];
Run Code Online (Sandbox Code Playgroud)
类似的构造存在几行较低,并且还需要修复(以及缩小的Javascript).