2009-01-20 53 views
4

我想拿出一個可以爲空的屬性,如int的驗證。企業庫驗證塊 - 驗證可爲空的屬性?

[RangeValidator(0, RangeBoundaryType.Inclusive, 1, RangeBoundaryType.Inclusive)] 
int? Age { get; set; } 

但是如果我設置Age爲null,因爲它並不在範圍不同。驗證失敗時,我知道我需要一個[ValidatorComposition(CompositionType.Or)]爲好,但我應該用什麼呢?

回答

5

您可以添加IgnoreNulls屬性:

[IgnoreNulls()] 
[RangeValidator(0, RangeBoundaryType.Inclusive, 1, RangeBoundaryType.Inclusive)] 
int? Age { get; set; } 
+0

只要驗證通過,就可以工作。如果失敗,那麼生成的ValidationResults將包含一個帶有RangeValidator的OrCompositeValidator作爲嵌套的ValidationResults之一,正如Paul指出的那樣。還有一個選擇 - 請參閱下面的答案。 – Philippe 2010-06-17 17:42:55

+0

-1因爲我相信@ Philippe的答案更有效。儘管我也認爲這是VAB中的重大監督。 – 2010-12-13 15:15:29

1

是的,但這時如果RangeValidator導致ValidationResult,然後由於某種原因,我結束了兩個ValidationResults ...一個正確的範圍驗證問題,但隨後另一個神祕的說:

該值不爲空,並且失敗了關鍵Age的所有驗證規則。

這是愚蠢的,我不希望驗證器IgnoreNulls導致驗證結果!它真的有修改其他的,不是嗎?在使用多態性時,缺乏真正的驗證繼承和功能,還有其他許多問題,並且VAB屬性存在如此多的「小」問題,我發現它不適用於任何非常重要的事情。

6

儘管可以添加IgnoreNulls屬性,但在返回驗證結果時會導致令人費解的ValidationResults。這是因爲驗證塊將驗證程序隱式包裝爲OrCompositeValidator - 該屬性可以爲null,或者它可以是指定範圍內的整數。

當驗證失敗時,頂級驗證結果爲OrCompositeValidator。要獲得實際的RangeValidator驗證結果,您現在需要深入探究ValidationResult對象上的NestedValidationResults屬性。

這似乎有很多工作來處理驗證結果消息,所以在我看來,必須有更好的方法。

這是我做的。

  1. 我創建了一個名爲IgnoreNullStringLengthValidator類從StringLengthValidator繼承(在這裏你將繼承RangeValidator)。
  2. 創建支持基礎構造函數所需的所有構造函數。
  3. 重寫DoValidate方法和檢查空值 - 在這裏你可以這樣寫:

    if (!objectToValidate.HasValue) return; 
    
  4. 確保你的下一行代碼調用base.DoValidate(...)
  5. 創建了一個名爲IgnoreNullStringLengthValidatorAttribute的屬性類,它返回新的IgnoreNullStringLengthValidator。在這裏,您將創建一個IgnoreNullRangeValidatorAttribute類。

由此產生的驗證結果更符合您的預期,因爲它不隱式嵌套驗證程序。