2010-01-11 90 views
12

我讀過Phil Haack's post關於ASP.NET MVC 2自定義客戶端驗證。我想要做同樣的事情,但與jQuery適配器和使用ASP.NET MVC 2 RC(而不是MVC 2 Beta的帖子使用)。有沒有人能夠知道如何做到這一點?如何在ASP.NET MVC 2 RC中編寫自定義客戶端jQuery驗證?

我特別想執行密碼匹配驗證(即密碼&確認密碼必須匹配)。 ASP.NET MVC 2 RC VS.NET項目模板確實展示瞭如何在服務器端實現它(使用PropertiesMustMatchAttribute),但不在客戶端。

+0

有排序的兩個問題在這裏: 1)你如何在客戶端做模型級驗證? 2)你如何使用jQuery執行驗證? 他們都是有趣的問題。您可能想要更新問題標題以合併該問題。 (我對#1的答案感興趣,但意外地發生在這個問題上。) – 2010-03-03 00:16:03

回答

15

我假設你已經跟着菲爾哈克的說明這裏http://haacked.com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx)如何讓自定義驗證與MS AJAX客戶端驗證工作。爲了得到它與jQuery的工作,你需要修改MicrosoftMvcJQueryValidation.js文件:

  • 在__MVC_CreateRulesForField(validationField)功能,你需要添加一個case語句。繼續菲爾的例子,你需要添加:

    情況下 「價格」:

    __MVC_ApplyValidator_Price(rulesObj,thisRule.ValidationParameters [ 「分鐘」]);

    break;

  • 然後,您需要創建__MVC_ApplyValidator_Price功能:

功能__MVC_ApplyValidator_Price(對象值){

// min is what jQuery Validate uses to validate for minimum values 
object["min"] = value; 

}

這應該足以讓菲爾的例如工作。

現在,關於您的PropertiesMustMatchAttribute驗證,它看起來不像MVC爲裝飾類的屬性生成客戶端json驗證定義。由於必須在模型上使用PropertiesMustMatchAttribute(而不是屬性),因此我無法弄清楚如何使其觸發客戶端驗證。相反,我採取了不同的方法。我創建了一個虛擬驗證屬性,它的IsValid()重載始終返回true,並在屬性上使用此屬性。這只是一個將驗證邏輯委託給jQuery驗證器的equalTo函數的虛擬屬性。這裏的虛擬屬性:

public class PropertiesMustMatchClientTriggerAttribute : ValidationAttribute 
{ 
    public string MatchProperty { get; set; } 

    public PropertiesMustMatchClientTriggerAttribute(string matchProperty) 
    { 
     MatchProperty = matchProperty; 
     ErrorMessage = "{0} doesn't match {1}."; 
    } 
    public override bool IsValid(object value) 
    { 
     return true; 
    } 

    public override string FormatErrorMessage(string name) 
    { 
     return String.Format(CultureInfo.CurrentCulture, ErrorMessageString, name, MatchProperty); 
    } 
} 

這裏是自定義的驗證:

public class PropertiesMustMatchClientTriggerValidator : DataAnnotationsModelValidator<PropertiesMustMatchClientTriggerAttribute> 
{ 
    private string _message; 
    private string _matchProperty; 

    public PropertiesMustMatchClientTriggerValidator(ModelMetadata metaData, ControllerContext context, PropertiesMustMatchClientTriggerAttribute attribute) 
     : base(metaData, context, attribute) 
    { 
     _message = attribute.FormatErrorMessage(metaData.DisplayName); 
     _matchProperty = attribute.MatchProperty; 
    } 

    public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() 
    { 
     var rule = new ModelClientValidationRule 
     { 
      ErrorMessage = _message, 
      ValidationType = "equalTo" 
     }; 
     rule.ValidationParameters.Add("matchField", _matchProperty); 

     return new[] { rule }; 
    } 
} 

上面的自定義驗證需要在的Application_Start()每菲爾的博客註冊:

DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof運算(PropertiesMustMatchClientTriggerAttribute),typeof(PropertiesMustMatchClientTriggerValidator));

最後,您需要修改MicrosoftMvcJQueryValidation。js文件:

  • 以下case語句添加到__MVC_CreateRulesForField:

案 「equalTo」:

__MVC_ApplyValidator_EqualTo(rulesObj,thisRule.ValidationParameters [ 「matchField」]);

break;

  • 添加此功能:

功能__MVC_ApplyValidator_EqualTo(對象,elemId){

object["equalTo"] = document.getElementById(elemId); 

}

現在你需要虛擬驗證屬性附加到屬性:

[PropertiesMustMatchClientTrigger("Password")] 
    public string ConfirmPassword { get; set; } 

這應該做到這一點。

創建這個虛擬屬性有點難看,所以我希望有人能想出一個更優雅的解決方案。

+0

感謝您的詳細解答。我會盡力並稍後更新結果。 – 2010-03-03 05:01:20

+0

只需對此進行快速跟進即可。基於Brad Wilson關於C4MVC的討論(http://www.viddler.com/explore/c4mvc/videos/24/),MVC團隊正在考慮在MVC 3中實現模型級註釋的客戶端驗證。如果他們這樣做那樣,這類問題就容易解決了。 – 2010-03-21 04:25:56

+0

最後我嘗試了你的解決方案,它的作用就像魅力。非常感謝! – 2010-04-08 10:20:48

1

以下是如何添加自定義的jQuery驗證:

$.validator.addMethod("noSpaces", function(value, element) { 
    if ($(element).val().indexOf(" ") >= 0) { 
     return false; 
    } else { 
     return true; 
    } 
}, "Value must not contain spaces"); 
+0

如何將該自定義方法集成到ASP.NET MVC 2的驗證引擎? – 2010-01-11 16:44:59

+0

根據菲爾的帖子,這個名字就應該做到這一點。但我還沒有嘗試過。 – 2010-01-11 16:52:25