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

时间:2014-04-11 09:26:35

标签: c# javascript jquery asp.net-mvc validation

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

MinFirstNameLength
FirstName
MinLastNameLength
LastName

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

所以,我使用了MVC不引人注目的客户端验证功能。我创建了一个自定义验证属性,实现了IClientValidatable接口。 GetClientValidationRules方法如下所示:

public IEnumerable<ModelClientValidationRule> 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;
}

此验证属性应用于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文件中有客户端验证函数,如下所示:

$.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;
});

我的问题是,如何在MinFirstNameLength的错误消息中将{0}的文本框中的值分配给占位符FirstName,以便错误消息显示为{{1} }}?

我尝试添加修改我的First Name must be at least [value] characters方法,如下所示:

$.validator.unobtrusive.adapters.add

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

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

$.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); }); });

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

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

1 个答案:

答案 0 :(得分:2)

我认为您应该在NameMinLength验证属性的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属性中的正确值替换占位符。在这种情况下,错误消息将被格式化,然后再将其移动到客户端。所以不需要额外的逻辑。

修改 嗯,只是认为你可能想根据用户输入进行验证,这真的很奇怪。实际上,对于同一个领域你可能有不同的最小长度限制这一事实对我来说没有意义,但只要它“#”;不是基于用户输入,它更安全。

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

编辑模型:

[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<ModelClientValidationRule> 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;
    }
});

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

希望它有所帮助!