2011-03-01 58 views
13

這更多的是一個理論問題。DataAnnotations如何在MVC中真正起作用?

我目前正在使用ComponentModel.DataAnnotations檢查MVC 3驗證,並且一切都自動工作,特別是在客戶端。

不知何故,某些東西會檢查這些屬性,並生成用於驗證的javascript(或html5屬性,如果使用不顯眼的模式),它就可以工作。

我的問題是,什麼產生客戶端JavaScript和我如何訪問和修改它?例如,我想處理給定的dataannotation屬性有點不同,或處理自定義屬性(我發現我可以從ValidationAttribute派生它們,但可能出於某種原因我不想)。

有人可以向我解釋真正發生了什麼? (或鏈接到好的解釋也將是好的,因爲我只找到實際使用數據註解的教程)

編輯:同時從派生ValidationAttribute,客戶端驗證不能自動工作。爲什麼?

回答

15

MVC3有鏈接jQuery的驗證和驗證屬性的元數據的新的jQuery驗證機制,這是jquery.validate.unobtrusive文件通吃data-屬性,並與他們一起工作,就像以前一樣,當你設置

<add key="UnobtrusiveJavaScriptEnabled" value="false" /> 

所有你需要做的就是拿出自己的自定義驗證屬性,對你有2種選擇:

  • 創建自定義驗證屬性繼承了ValidationAttribute接口和 覆蓋IsValid

  • 創建自我驗證模式使用模型IValidatebleObject,所有你需要的是返回Validate方法

in MVC3你現在hav您可以覆蓋的方法有一個ValidationContext對象,您可以簡單地獲取所有其他對象的所有引用,屬性和值的形式

創建您自己的,並且該不顯眼的文件將處理您的自定義的映射驗證器的需求,並將與jQuery驗證插件一起解決。

你不改變javascript ...這是90年代而不是MVC的方式!

例如,如果您想驗證,比方說2日,最後不能小於

public class TimeCard 
{ 
    public DateTime StartDate { get; set; } 

    [GreaterThanDateAttribute("StartDate")] 
    public DateTime EndDate { get; set; } 
} 

創建第一個(的時間,例如週期)一自定義驗證

public class GreaterThanDateAttribute : ValidationAttribute 
{ 
    public string GreaterThanDateAttribute(string otherPropertyName) 
     :base("{0} must be greater than {1}") 
    { 
     OtherPropertyName = otherPropertyName; 
    } 

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

    public override ValidateionResult IsValid(object value, ValidationContext validationContext) 
    { 
     var otherPropertyInfo = validationContext.ObjectTYpe.GetProperty(OtherPropertyName); 
     var otherDate = (DateTime)otherPropertyInfo.GetValue(validationContext.ObjectInstance, null); 
     var thisDate = (DateTime)value; 

     if(thisDate <= otherDate) 
     { 
      var message = FormatErrorMessage(validationContext.DisplayName); 
      return new ValidationResult(message); 
     } 

     return null;   
    }  
} 

如果使用自我驗證模型,則代碼將只是

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 
{ 
    if(EndDate <= StartDate) 
     yield return new ValidationResult("EndDate must be grater than StartDate"); 
} 

請記住,自定義驗證是通用的,這就是爲什麼很多代碼和自我驗證模型只適用於應用的模型。

希望它可以幫助


添加

我沒有解釋自定義客戶端驗證部分,下跌免費問,如果你需要的例子,但基本上是:

在MVC3中更容易(當然,如果您瞭解jQuery.Validate),您只需要:

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

要創建此三件事情,讓我們這個GreaterThanDateAttribute考慮在內,並創建自定義客戶端驗證。爲此,我們需要實現代碼:

追加到GreaterThanDateAttribute

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.Validation與您的代碼鏈接提供正確的data-屬性該字段(如果當然,UnobtrusiveJavaScriptEnabled爲true)

創建一個新的文件js,重視你的<head>爲examp樂爲

<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; 
}); 
+0

謝謝您的回答。自我驗證模型對我來說是一種新的方法。 但你誤解了這個問題。我對創建自定義驗證屬性並不感興趣,但對JavaScript(或html5屬性,如果選擇不顯眼模式)從驗證屬性生成的方式感興趣。 對不起,我強迫一個幼稚的例子說明這些知識如何有用,但這真的不是我的文章的重點。此外,你的答案是非常好的。 – SoonDead 2011-03-01 13:53:33

+1

對不起,但我沒跟着。你想知道'data-'是如何生成的?這是幫助程序'Html.TextBoxFor()'方法的工作,因爲它已經知道該字段需要的所有數據解析,並且如果Unobstrutive設置爲true,它將生成他需要的所有'data-',然後Adapter鏈接那入jQuery.Validate插件。隨便問個例子,我可以在'GreaterThanDateAttribute'上面的例子中看到這些,或許它可以幫助你更好地理解它。 – balexandre 2011-03-01 14:03:37

+0

添加了自定義客戶端驗證示例,創建並使用它,以便您可以查看「自定義客戶端驗證」的功能。它將增加''屬性'data-val'和'data-val-greater'以及執行客戶端驗證的所有必需屬性。 **這個最後一個例子能回答你的問題嗎? – balexandre 2011-03-01 14:20:23

相關問題