2012-02-19 129 views
1

我已經創建了一個派生自ValidationAttribute的自定義驗證器。我的undertsandng是它會爲客戶端腳本生成足夠的元數據來自動驗證(使用jquery.validate)。自定義驗證器在服務器端工作正常。但它不會在客戶端觸發錯誤消息。 (像「StringLength」這樣的其他默認驗證器在客戶端也可以正常工作。)我們如何糾正它?使用ValidationAttribute進行自定義驗證不會觸發客戶端驗證

public class Person 
{ 
    [Required(ErrorMessage = "First name required")] 
    public string FirstName { get; set; } 

    [CustomStartLetterMatch("FirstName")] 
    [StringLength(5,ErrorMessage = "Must be under 5 characters")] 
    public string LastName { get; set; } 

    [Range(18,50,ErrorMessage="Must be between 18 and 50")] 
    public int Age { get; set; } 


} 


public sealed class CustomStartLetterMatch : ValidationAttribute 
{ 

    private const string _defaultErrorMessage = " First letter of '{0}' must be same as first letetr of '{1}'"; 
    private string _basePropertyName; 

    public CustomStartLetterMatch(string basePropertyName) 
     : base(_defaultErrorMessage) 
    { 
     _basePropertyName = basePropertyName; 
    } 


    //Override FormatErrorMessage Method 
    public override string FormatErrorMessage(string name) 
    { 
     return string.Format(_defaultErrorMessage, name, _basePropertyName); 
    } 


    //Override IsValid 
    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     //Get PropertyInfo Object 
     var basePropertyInfo = validationContext.ObjectType.GetProperty(_basePropertyName); 
     var baseValue = (string)basePropertyInfo.GetValue(validationContext.ObjectInstance, null); 
     var currentValue = (string)value; 


     string firstLetterBaseValue = baseValue.Substring(0, 1); 
     string firstLetterCurrentValue = currentValue.Substring(0, 1); 

     //Comparision 
     if (!string.Equals(firstLetterBaseValue, firstLetterCurrentValue)) 
     { 
      var message = FormatErrorMessage(validationContext.DisplayName); 
      return new ValidationResult(message); 
     } 

     //Default return - This means there were no validation error 
     return null; 
    } 

} 

VIEW

@model MyValidationTEST.Person 

<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"> </script> 

@*UnObtrusive*@ 
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> 




@using (Html.BeginForm()) { 
@Html.ValidationSummary(true) 
<fieldset> 
    <legend>Person</legend> 

    <div class="editor-label"> 
     @Html.LabelFor(model => model.FirstName) 
    </div> 
    <div class="editor-field"> 
     @Html.EditorFor(model => model.FirstName) 
     @Html.ValidationMessageFor(model => model.FirstName) 
    </div> 

    <div class="editor-label"> 
     @Html.LabelFor(model => model.LastName) 
    </div> 
    <div class="editor-field"> 
     @Html.EditorFor(model => model.LastName) 
     @Html.ValidationMessageFor(model => model.LastName) 
    </div> 

    <div class="editor-label"> 
     @Html.LabelFor(model => model.Age) 
    </div> 
    <div class="editor-field"> 
     @Html.EditorFor(model => model.Age) 
     @Html.ValidationMessageFor(model => model.Age) 
    </div> 



    <p> 
     <input type="submit" value="Create" /> 
    </p> 
</fieldset> 
} 

<div> 
@Html.ActionLink("Back to List", "Index") 
</div> 

閱讀:

  1. IValidatableObject in MVC3 - client side validation

  2. In ASP.NET MVC3 how do you stay DRY with very similar but slightly different viewmodels?

  3. http://odetocode.com/Blogs/scott/archive/2011/02/22/custom-data-annotation-validator-part-ii-client-code.aspx

  4. http://bradwilson.typepad.com/blog/2010/10/mvc3-unobtrusive-validation.html

  5. ASP.NET MVC 3 client-side validation with parameters

  6. How can I have a custom ValidationAttribute rendered as a 'data-val-xx' attribute on the client-side?

  7. Clientside Validation in "Self Validate Model" in ASP.NET-MVC3

回答

5

我undertsandng是,它會根爲 客戶端腳本提供足夠的元數據來自動驗證(使用jquery.validate)。

你的理解是錯誤的。您不可能期望有足夠的元數據來生成客戶端驗證。在這個IsValid方法你可以做任何事情。您甚至可以調用非託管C++庫來執行驗證。你不可能期望ASP.NET MVC 3會在客戶端反映這一點。

您需要實現IClientValidatable,如果你要啓用此類定製驗證邏輯客戶端驗證添加自定義適配器。在這個適配器中,你必須重新實現你在服務器上做的同樣的邏輯,但是這次使用javascript。

這是one example。這裏是another one

正如你可以看到客戶端驗證正常工作與一些簡單的規則,如必需之類的東西,有點一旦你開始做一些真正的驗證功能,你將不得不自己實現它。

+0

謝謝。所以它不是真的幹嗎? :-)如果它是自定義驗證,我們需要重複。 – Lijo 2012-02-19 11:00:07

+1

@Lijo,是的,它不是乾的。但事情就是這樣。爲什麼麻煩在客戶端上實現這樣的自定義規則呢?當然,如果你絕對需要它,準備自己寫javascript。 – 2012-02-19 11:01:06

+0

謝謝。還有一個問題。如果我使用自我驗證方法,是否可以編寫這樣的客戶端腳本? – Lijo 2012-02-19 11:04:49

相關問題