2013-08-01 78 views
0

我試圖對未綁定到UI的對象執行一些驗證。例如,我有以下三類:企業庫對象驗證:獲取有關驗證失敗的更多信息

public class XDeftable { 
    [ObjectCollectionValidator(typeof(XSchedGroup))] 
    public List<XSchedGroup> SCHED_GROUP { get; set; } 
} 

[IdentifyingProperty("TABLE_NAME")] 
public class XSchedGroup { 
    [ObjectCollectionValidator(typeof(XJob))] 
    public List<XJob> JOB { get; set; } 
    [Required] 
    public string TABLE_NAME { get; set; } 
} 

[IdentifyingProperty("JOBNAME")] 
public class XJob : ICalendar { 
    [Required] 
    public string JOBNAME { get; set; } 
    [Range(-62, 62)] 
    public string SHIFTNUM { get; set; } 
    [ObjectCollectionValidator(typeof(XTagNames))] 
    public List<XTagNames> TAG_NAMES { get; set; } 
} 

XDeftable - > XSchedGroup - > XJob - > XTagNames

當一個對象未​​通過驗證工作的事情完全按照人們所期望的,但如果我只是檢查的ValidationResult因爲它是密鑰消息我最終得到了類似於:「JOBNAME | Field is required。」

的問題,這是考慮到我可能有數百個就業機會在一個調度組的驗證是無用的,因爲我不知道哪一個特定作業失敗做。我搜索了關於驗證和C#的各種文檔,並且沒有找到獲取更多數據的方法。我創建了屬性IdentifyingProperty以允許我標記該類的哪個屬性標識了該類的特定實例。我有一個基於Git Repo:https://github.com/reustmd/DataAnnotationsValidatorRecursive/tree/master/DataAnnotationsValidator/DataAnnotationsValidator的以前的自定義驗證解決方案。它工作正常,但我想交換更強大的東西。

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] 
public sealed class IdentifyingProperty : Attribute { 
    public string Name { get; set; } 

    public IdentifyingProperty(string name) { 
     this.Name = name; 
    } 
} 

到目前爲止,我已經能夠想出如下:

這至少會回到我「XJob [作業名] .SHIFTNUM |現場SHIFTNUM必須介於 - 62和62.「我仍然喜歡它,如果有一種方法可以讓我獲得跟隨容器鏈的結果,例如:XSchedGroup [TABLE_NAME] .XJob [JOBNAME] .SHIFTNUM

+0

請注意,這不是特定於C#編程語言:

所以你的方法是這樣堅持。 –

+0

@JohnSaunders編輯標籤到.Net。 – Kittoes0124

+0

非常好。我已經改變了標題。 –

回答

0

我用過一次

 public class RequiredPropertyAttribute : Attribute 
     { 
      public bool Required { get { return true; } } 
     } 
     public class RequiredListAttribute : Attribute 
     { 
      public bool Required { get { return true; } } 
     } 

相似,東西驗證以下。它會根據我指定的屬性進行檢查,並返回哪些不需要填充的屬性。

  public List<string> IterateProperties(object _o) 
      { 
       List<string> problems = new List<string>(); 

       foreach (PropertyInfo info in _o.GetType().GetProperties()) 
       { 
        bool isGenericType = info.PropertyType.IsGenericType; 
        Type infoType = info.PropertyType; 

        if (infoType.IsGenericType && infoType.GetGenericTypeDefinition() == typeof(List<>)) 
        { 
         infoType = infoType.GetGenericArguments()[0]; 

         if (infoType.IsNested) 
         { 
          System.Collections.IList subObjects = (System.Collections.IList)info.GetValue(_o, null); 

          object[] requiredListAttributes = info.GetCustomAttributes(typeof(RequiredListAttribute), true); 
          if (requiredListAttributes.Length > 0 && subObjects.Count == 0) 
          { 
           problems.Add(String.Format("List {0} in class {1} must have at least 1 row", info.Name, info.PropertyType.ToString())); 
          } 
          else 
          { 
           foreach (object sub in subObjects) 
           { 
            problems.AddRange(this.IterateProperties(sub)); 
           } 
          } 
         } 
        } 
        else 
        { 
         if (infoType.IsNested) 
         { 
          object sub = info.GetValue(_o, null); 
          if (sub != null) 
          { 
           problems.AddRange(this.IterateProperties(sub)); 
          } 
         } 
        } 


        object[] attributes = info.GetCustomAttributes(typeof(RequiredPropertyAttribute), true); 
        foreach (object o in attributes) 
        { 
         if (info.GetValue(_o, null) == null) 
         { 
          problems.Add(String.Format("Attribute {0} in class {1} cannot be null", info.Name, info.PropertyType.ToString())); 
         } 
        } 
       } 

       return problems; 
      } 
     } 
+0

對不起,但並不真正在尋找什麼。企業庫的驗證塊正在處理我所有的驗證工作。它沒有做的是記錄足夠的信息讓我去做任何有關驗證失敗的事情。它只顯示未通過驗證的屬性的名稱以及錯誤消息,說明它爲什麼失敗。 – Kittoes0124

1

相反操作鍵的,我會因爲這正是它是(「爲標籤的含義是由客戶端代碼消耗ValidationResults決定」),背馱式上的Tag屬性。

public ValidationResults Validate(XDeftable deftable) 
{ 
    var results = new ObjectValidator(typeof(XDeftable)).Validate(deftable); 
    var detailedResults = new ValidationResults(); 

    Microsoft.Practices.EnterpriseLibrary.Validation.ValidationResult result = null; 

    foreach (var item in results) 
    { 
     result = item; 

     var targetType = item.Target.GetType(); 

     var attribute = (IdentifyingPropertyAttribute) 
          targetType.GetCustomAttributes(
           typeof(IdentifyingPropertyAttribute), 
           false) 
          .SingleOrDefault(); 

     if (attribute != null) 
     { 
      var propertyInfo = targetType.GetProperty(attribute.Name); 

      if (propertyInfo != null) 
      { 
       object propertyValue = propertyInfo.GetValue(item.Target) ?? ""; 

       result = new Microsoft.Practices.EnterpriseLibrary.Validation.ValidationResult(
          item.Message, 
          item.Target, 
          item.Key, 
          propertyValue.ToString(), 
          item.Validator); 
      } 
     } 

     detailedResults.AddResult(result); 
    } 

    return detailedResults; 
} 
+0

有沒有一種方法可以讓每個「父母」?如果我能得到整個對象的層次結構,它對於調試/日誌記錄確實很有幫助。 – Kittoes0124

+0

ValidationResult包含對已驗證的目標對象的引用。但是,沒有關於圖中存在該對象的概念。我能想到的唯一方法就是給每個班級添加一些額外的數據和你想要的信息。例如。一個'ParentName'屬性(通過接口或基類),所有對象都可以通過Target對象找到它。 –