2009-01-20 51 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类。

由此产生的验证结果更符合您的预期,因为它不隐式嵌套验证程序。