2014-04-11 16 views
1

我使用MVC5,我有一個視圖模型爲我的視圖,其中包含一個簡單的形式與以下字段:如何在運行時使用jQuery更改MVC自定義客戶端驗證錯誤消息?

MinFirstNameLength 
FirstName 
MinLastNameLength 
LastName 

現在,我想申請上FirstName驗證規則的基礎上的價值,以及類似的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,以便錯誤消息讀取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自動替換。

此錯誤消息來自哪裏?如何在運行時修改它?

回答

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}。

希望它有幫助!

+0

在「IsValid」方法內部格式化錯誤消息會破壞客戶端驗證的整個目的。我希望能夠根據用戶輸入更改客戶端本身的錯誤消息,並保存服務器行程。所以我認爲我必須在JavaScript代碼中做一些事情。但是什麼? 此外,我想根據用戶輸入進行驗證。我正在做的實際事情有點複雜。我在這裏描述的只是我創建的一個例子來說明我正面臨的確切問題。 –

+0

@AmateurProgrammer請參閱我的答案更新,做了一個具有類似屬性的簡單測試,它在客戶端進行驗證時將文本框中的值替換爲{0}。 –

+0

@MaksymStrukov類似的問題,我試過你的方法,但我的錯誤被驗證器的內部重寫:$ .validator.format(message.replace(theregex,「{$ 1}」),rule.parameters);這將{0}更改爲[對象對象],其餘錯誤消息顯示。 – Vyache

相關問題