2012-09-28 41 views
0

我有一個對象(頭),有我想要做的之前接收數據的自定義驗證子ojects(詳細信息)的列表怎麼辦。我試過ModelState.IsValid和TryValidateModel,但是它似乎沒有在子對象(只有頭對象)上觸發Validate方法。我做子對象的自定義驗證MVC3

所以在提交時,我看到了標題驗證火,但沒有看到子項。然後,如果我做了TryValidateModel,我再次看到(斷點)在頭上調用的驗證方法,而不是在子對象上調用。

的註解驗證(必須是數字,等...),似乎是工作的子對象,只是沒有通過IValidatableObject接口添加的自定義邏輯。任何幫助將不勝感激。

回答

0

的TryValidateObject沒有出現觸發關閉驗證發射自定義驗證,只有數據註釋?我去了通過以下操作添加的細節驗證到頁眉驗證的路徑:

foreach (var detail in this.Details) 
{ 
    var validationResults = detail.Validate(validationContext); 
    foreach (var validationResult in validationResults) 
    { 
     yield return validationResult; 
    } 
} 

這個工作在驗證方面,但是UI沒有顯示錯誤消息。即使我在UI上有ValidationMessagesFor。

驗證不工作解決此:MVC3 Master-Details Validation not Displaying

0

我不知道你的根對象是否有錯誤,防止孩子驗證。 見Recursive validation using annotations and IValidatableObject 此URL提到的場景,也代碼強制驗證的孩子從根

按照張貼從根對象

 

    public IEnumerable Validate(ValidationContext validationContext) 
    { 
     var context = new ValidationContext(this.Details, validationContext.ServiceContainer, validationContext.Items); 
     var results = new List(); 
     Validator.TryValidateObject(this.Details, context, results); 
     return results; 
    } 
 
+0

它看起來不像根對象有錯誤(非預期的和ModelState.IsValid = true) – ChrisHDog

+0

請嘗試另一個建議,以確保根證實驗證方法中的孩子在該帖子中顯示或使用屬性基於方法。 –

1

我做一個屬性([ValidateObject]),它會驗證你把你的階級屬性,就像你會覺得它該做的。

public class Personne 
{ 
    [ValidateObject] 
    public Address Address { get; set; } 
    //[...] 
} 

(地址是一個自定義類。)

它可用於驗證:

  • 上的模型對象屬性。 (如上)
  • 子對象的集合。

    [ValidateObject] 
    public List<Address> Address { get; set; } 
    
  • 它支持部門的多的水平,如果「地址」有類型「郵編」與屬性的propertie [ValidateObject]這將是驗證壽。

代碼:

public class ValidateObjectAttribute : ValidationAttribute 
{ 
    public ValidateObjectAttribute() 
    { 

    } 
    private ValidationContext ValidationContext { get; set; } 
    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     this.ValidationContext = validationContext; 
     var results = new List<ValidationResult>(); 

     try 
     { 
      var isIterable = this.IsIterable(value); 
      if (isIterable) 
      { 
       int currentItemPosition = -1; 
       foreach (var objectToValidate in value as IEnumerable<object>) 
       { 
        currentItemPosition++; 
        var resultTemp = ValidationsForObject(objectToValidate, true, currentItemPosition); 
        if (resultTemp != null) 
         results.AddRange(resultTemp); 

       } 
       if (results.Count <= 0) 
        results = null; 
      } 
      else 
       results = ValidationsForObject(value); 

      if (results != null) 
      { 
       //Build a validation result 
       List<string> memberNames = new List<string>(); 
       results.ForEach(r => memberNames.AddRange(r.MemberNames)); 

       var compositeResultsReturn = new CompositeValidationResult($"Validation for {validationContext.DisplayName} failed!", memberNames.AsEnumerable()); 
       results.ForEach(r => compositeResultsReturn.AddResult(r)); 

       return compositeResultsReturn; 
      } 

     } 
     catch (Exception) { } 

     return ValidationResult.Success; 
    } 

    private List<ValidationResult> ValidationsForObject (object objectToValidate, bool IsIterable = false, int position = -1) 
    { 
     var results = new List<ValidationResult>(); 
     var contextTemp = new ValidationContext(objectToValidate, null, null); 
     var resultsForThisItem = new List<ValidationResult>(); 

     var isValid = Validator.TryValidateObject(objectToValidate, contextTemp, resultsForThisItem, true); 
     if (isValid) 
      return null; 

     foreach (var validationResult in resultsForThisItem) 
     { 
      List<string> propNames = new List<string>();// add prefix to properties 
      foreach (var nameOfProp in validationResult.MemberNames) 
      { 
       if (IsIterable) 
        propNames.Add($"{this.ValidationContext.MemberName}[{position}].{nameOfProp}"); 
       else 
        propNames.Add($"{this.ValidationContext.MemberName}.{nameOfProp}"); 
      } 
      var customFormatValidation = new ValidationResult(validationResult.ErrorMessage, propNames); 
      results.Add(customFormatValidation); 
     }  

     return results; 
    } 


    private bool IsIterable(object value) 
    { 
     ////COULD WRITE THIS, but its complicated to debug... 
     //if (value.GetType().GetInterfaces().Any(
     //i => i.IsGenericType && 
     //i.GetGenericTypeDefinition() == typeof(IEnumerable<>))) 
     //{ 
     // // foreach... 
     //} 
     Type valueType = value.GetType(); 
     var interfaces = valueType.GetInterfaces(); 
     bool isIterable = false; 
     foreach (var i in interfaces) 
     { 
      var isGeneric = i.IsGenericType; 
      bool isEnumerable = i.GetGenericTypeDefinition() == typeof(IEnumerable<>); 
      isIterable = isGeneric && isEnumerable; 
      if (isIterable) 
       break; 
     } 
     return isIterable; 
    } 
} 

public class CompositeValidationResult : ValidationResult 
{ 
    private readonly List<ValidationResult> _results = new List<ValidationResult>(); 

    public IEnumerable<ValidationResult> Results 
    { 
     get 
     { 
      return _results; 
     } 
    } 

    public CompositeValidationResult(string errorMessage) : base(errorMessage) 
    { 
    } 

    public CompositeValidationResult(string errorMessage, IEnumerable<string> memberNames) : base(errorMessage, memberNames) 
    { 
    } 

    protected CompositeValidationResult(ValidationResult validationResult) : base(validationResult) 
    { 
    } 

    public void AddResult(ValidationResult validationResult) 
    { 
     _results.Add(validationResult); 
    } 
} 

這將工作,如果你的模型是否正確綁定:)

您可能需要添加所需的屬性,確保對象不爲空本身。

[Required] 

希望它有幫助!