如何使用jQuery在运行时更改MVC自定义客户端validation错误消息?

我正在使用MVC5,我的View有一个ViewModel,它包含一个包含以下字段的简单表单:

MinFirstNameLength FirstName MinLastNameLength LastName 

现在,我希望根据MinFirstNameLength的值对FirstName应用validation规则,对于使用MinLastNameLength LastName应用validation规则。 我也想在客户端这样做。

所以,我使用了MVC不显眼的客户端validationfunction。 我创建了一个自定义validation属性,实现了IClientValidatable接口。 GetClientValidationRules方法如下所示:

 public IEnumerable GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { string ErrorMessage = ErrorMessageString; ModelClientValidationRule NameMinLengthRule = new ModelClientValidationRule(); NameMinLengthRule.ErrorMessage = ErrorMessage; NameMinLengthRule.ValidationType = "nameminlength"; NameMinLengthRule.ValidationParameters.Add("minlengthpropname", MinLengthPropName); yield return NameMinLengthRule; } 

此validation属性应用于FirstNameLastName属性,如下所示:

 [NameMinLength("FirstNameMinLength",ErrorMessage = "First Name must be at least {0} characters"] public string FirstName { get; set; } [NameMinLength("LastNameMinLength",ErrorMessage = "Last Name must be at least {0} characters"] public string LastName { get; set; } 

另外,我在其他地方的.js文件中有客户端validation函数,如下所示:

 $.validator.addMethod("nameminlength", function ( value, element, params ) { return value.length >= parseInt($(params).val()); }); $.validator.unobtrusive.adapters.add("nameminlength", ["minlengthpropname"], function (options) { var paramField = "#" + options.params.minlengthpropname; options.rules["nameminlength"] = paramField; var errormessage = options.message; options.messages["nameminlength"] = errormessage; }); 

我的问题是,如何在我的FirstName错误消息MinFirstNameLength的文本框中的值分配给占位符{0} ,以便错误消息显示First Name must be at least [value] characters

我尝试添加修改我的$.validator.unobtrusive.adapters.add方法,如下所示:

 $.validator.unobtrusive.adapters.add("nameminlength", ["minlengthpropname"], function (options) { var paramField = "#" + options.params.minlengthpropname; options.rules["nameminlength"] = paramField; var errormessage = options.message; options.messages["nameminlength"] = errormessage; $(paramField).blur(function () { // change error message in the 'data-val-nameminlength' attribute of the HTML element on which validation is applied var newErrorMessage = options.messages["nameminlength"].replace("{0}", $(paramField).val()); $(options.element).attr("data-val-nameminlength", newErrorMessage); // change error message inside the error message span generated for displaying this error $(options.element).siblings(".field-validation-valid").html(newErrorMessage); }); }); 

但这两种技巧都行不通。 HTML标记确实已更改以适当地修改错误,但此更改未反映在页面中。

目前,我看到的错误消息是:

First Name must be at least #FirstNameMinLength characters

占位符由控件的id自动替换,该控件的id用作validation规则中的参数。

此错误消息来自哪里? 如何在运行时修改它?

我认为您应该在NameMinLengthvalidation属性的IsValid方法中在服务器端格式化您的消息。 这是一个关于如何做的小例子。

 protected override ValidationResult IsValid(object value, ValidationContext validationContext) { var conditionalPropertyInfo = validationContext.ObjectType.GetProperty(this.MinLengthPropName); var conditionalPropertyValue = conditionalPropertyInfo.GetValue(validationContext.ObjectInstance, null); this.ErrorMessage = string.Format(this.ErrorMessage, conditionalPropertyValue.ToString()) // YOUR OTHER CODE HERE } 

这应该使用MinLengthPropName属性中的正确值替换占位符。 在这种情况下,错误消息将在将其移动到客户端之前进行格式化。 因此,不需要额外的逻辑。

编辑:嗯,只是认为你可能想根据用户输入进行validation,这真的很奇怪。 实际上你可能对同一个字段有不同的最小长度限制这一事实对我来说没有意义,但只要它不是基于用户输入它就更安全。

更新客户端解决方案:
我做了一个类似属性的简单测试,它对我有用

编辑模型:

 [MinCustomLength("MinLenthDestURI", "Dest URI must be at least {0} characters")] public string DestinationURI { get; set; } public int MinLenthDestURI { get; set; } 

属性代码:

 public class MinCustomLengthAttribute : ValidationAttribute, IClientValidatable { private String PropertyName { get; set; } public MinCustomLengthAttribute(String propertyName, String errormessage) { this.PropertyName = propertyName; this.ErrorMessage = errormessage; } protected override ValidationResult IsValid(object value, ValidationContext context) { // Just for test server side validation always returns Success return ValidationResult.Success; } public IEnumerable GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { var modelClientValidationRule = new ModelClientValidationRule { ValidationType = "mincustomlength", ErrorMessage = this.ErrorMessage }; modelClientValidationRule.ValidationParameters.Add("prop", PropertyName); yield return modelClientValidationRule; } } 

客户端代码:

 $.validator.addMethod("mincustomlength", function (value, element, params) { var conditionalId = $.validator.getId(element, params.prop); var minLength = parseInt($("#" + conditionalId).val()); if (value.length < minLength) { var message = $(element).attr('data-val-mincustomlength'); $.validator.messages.mincustomlength = $.format(message, minLength); return false; } return true; }); $.validator.unobtrusive.adapters.add('mincustomlength', ['prop'], function (options) { options.rules['mincustomlength'] = options.params; if (options.message != null) { $.validator.messages.mincustomlength = options.message; } }); 

validation完成后,这将使用MinLenthDestURI文本框中的值替换{0}。

希望能帮助到你!