2011-03-01 86 views
3

這是此問題的後續問題:How does DataAnnotations really work in MVC? 有一個示例自定義驗證,並提到了「自我驗證模型」。這很有趣,但我不明白如何爲它編寫客戶端驗證。ASP.NET-MVC3中的「自我驗證模型」中的客戶端驗證

我的模型對象是否可以實現IClientValidateble接口(或僅用於dataannotation屬性?),我希望看到有關如何實現它的示例。

編輯:就我的理解,「自我驗證模型」在不使用DataAnnotations的情況下工作,並在我正在驗證的屬性中聲明驗證邏輯,而且它不是(必然)使用屬性來驗證某些內容。

我在自定義客戶端驗證中看到的所有示例都是關於實現IClientValidatable的數據註解屬性

當我在我的類中聲明我的驗證邏輯時,我不使用屬性來驗證模型狀態。

當我在實現IValidatebleObject接口的模型類的Validate方法中聲明我的驗證邏輯時,如何編寫clientside驗證?

我真的傳遞給視圖的類是否可以實現IClientValidatable接口或類似的東西?

回答

2

採取了相同的答案:

後你實現自我驗證模型,女巫是一個服務器端驗證,你需要創建客戶端驗證部分,對於這一點,只需創建此3個步驟:

  • 實施
  • 實現一個jQuery驗證方法
  • 實現一個不顯眼的適配器

追加到IClientValidateble

public IEnumerable<ModelClientValidation> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
{ 
    var rule = new ModelCLientValidationRule(); 
    rule.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()); 
    rule.ValidationType = "greater"; // This is what the jQuery.Validation expects 
    rule.ValidationParameters.Add("other", OtherPropertyName); // This is the 2nd parameter 

    yield return rule; 
} 

然後,你需要編寫新jQuery的驗證元數據適配器將鏈接jQuery的。驗證你的代碼提供正確的data-屬性該字段(如果當然,UnobtrusiveJavaScriptEnabled爲true)

創建一個新的js文件,並連接到您的<head>例如,作爲

<script src="@Url.Content("~/Scripts/customValidation.js")" type="text/javascript"></script> 

並追加新驗證

jQuery.validator.addMethod("greater", function(value, element, param) { 
    // we need to take value and compare with the value in 2nd parameter that is hold in param 
    return Date.parse(value) > Date.parse($(param).val()); 
}); 

,然後我們寫的適配器

jQuery.validator.unobtrusive.adapters.add("greater", ["other"], function(options) { 
    // pass the 'other' property value to the jQuery Validator 
    options.rules["greater"] = "#" + options.param.other; 
    // when this rule fails, show message that comes from ErrorMessage 
    options.messages["greater"] = options.message; 
}); 

當你創建一個新的Web MVC3您Applicatoin可以在AccountModel.cs查看此,它表明這種方法實現了IClientValidatable

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)] 
public sealed class ValidatePasswordLengthAttribute : ValidationAttribute, IClientValidatable 
{ 
    private const string _defaultErrorMessage = "'{0}' must be at least {1} characters long."; 
    private readonly int _minCharacters = Membership.Provider.MinRequiredPasswordLength; 

    public ValidatePasswordLengthAttribute() 
     : base(_defaultErrorMessage) 
    { 
    } 

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

    public override bool IsValid(object value) 
    { 
     string valueAsString = value as string; 
     return (valueAsString != null && valueAsString.Length >= _minCharacters); 
    } 

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
    { 
     return new[]{ 
      new ModelClientValidationStringLengthRule(FormatErrorMessage(metadata.GetDisplayName()), _minCharacters, int.MaxValue) 
     }; 
    } 
} 
#endregion 
+0

我更新的問題更加清晰。 – SoonDead 2011-03-01 15:06:50

+1

這顯然不像以前那樣是一回事,因爲在這裏他會詢問是否可以在每個屬性上使用IClientValidatable WITHOUT(dataannotain)屬性!你的答案包含'public sealed class ValidatePasswordLengthAttribute:ValidationAttribute,IClientValidatable',所以這顯然不是一個正確的答案! – TDaver 2011-03-04 12:56:13