【问题标题】:Custom ValidationAttribute doesn't work. Always returns true自定义 ValidationAttribute 不起作用。总是返回真
【发布时间】:2015-06-08 23:51:25
【问题描述】:

我创建了一个自定义 ValidationAttribute 类来检查我的应用程序中的人的年龄:

public class MinimumAgeAttribute : ValidationAttribute
{
    public int MinAge { get; set; }

    public override bool IsValid(object value)
    {
        return CalculateAge((DateTime) value) >= MinAge;
    }

    private int CalculateAge(DateTime dateofBirth)
    {
        DateTime today = DateTime.Now;
        int age = today.Year - dateofBirth.Year;
        if (dateofBirth > today.AddYears(-age)) age--;
        return age;
    }
}

在字段上设置数据注释是这样的:

[MinimumAge(MinAge = 18, ErrorMessage = "Person must be over the age of 18")]   
public DateTime DateOfBirth;

我的 UI 中的绑定设置如下:

<DatePicker SelectedDate="{Binding SelectedPerson.DateOfBirth, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" Grid.Column="1"/>

例如,当我将日期(例如)设置为 09/06/2007 时,Validator.TryValidateObject 总是返回 true。

为什么?这似乎只会影响我的自定义类,System.ComponentModel.DataAnnotations 中提供的所有类都可以正常工作。

【问题讨论】:

  • 不确定这是否能解决您的问题,但在处理日期时,请始终考虑您转换的文化。你有一个从objectDateTime 的直接转换。
  • 你有没有通过你的代码来查看变量的值是什么? CalculateAge 为您的示例日期返回什么?
  • 也许这个答案可能会有所帮助:stackoverflow.com/questions/29665290/…
  • @Ron CalculateAge 永远不会被调用。
  • 从上面显示的代码中,我假设您正在使用 WPF。这是正确的吗?

标签: c# data-annotations


【解决方案1】:

您的自定义 ValidationAttribute 类不起作用的原因是 WPF 在进行验证时(默认情况下)不查看此类类。验证的默认机制是实现 IDataErrorInfo(适用于 .NET 4.0 和更早版本)或 INotifyDataErrorInfo(在 .NET 4.5 中引入)接口。如果您不想实现这些接口中的任何一个,那么您可以创建一个 ValidationRule,但我更喜欢实现上面提到的接口。

您可以在网上找到很多关于如何执行此操作的示例,但通过快速搜索找到了这个blog post(快速浏览后我觉得非常彻底)。


编辑

由于您似乎更热衷于使用数据注释而不是 IDataErrorInfo/INotifyDataErrorInfo 接口或验证规则,我认为 Microsoft TechNet 文章"Data Validation in MVVM" 是使用数据注释进行验证的非常干净和彻底的实现。我自己通读了该解决方案,并将其推荐给其他人。

【讨论】:

  • 我以前看过那个帖子,其他人也喜欢。但是我一直在与自己争论我是否正确地实现了这一点,因为我最终得到了 200 多个行索引器和方法以及 40 多个类,它们都做同样的事情,只是在语法上略有不同。
  • @Jake,很遗憾听到这个消息。但是您是否尝试过使用 ValidationRule。对于跨不同类所需的数据验证功能,它似乎非常接近 ValidationAttribute。否则,建议使用索引器和方法。
  • 如果我正在考虑您正在考虑的 ValidationRule 类,这将再次以包含大约 40 个类的命名空间结束,这对我来说似乎是不好的编程习惯,除非我'我没抓住重点?
  • 我在想一个 CustomValidationRule,它可以充当适配器来查看当前属性是否具有 ValidationAttribute,如果有,则调用 ValidationAttribute 的验证方法。这将使您的数据绑定语句更长,因为您必须告诉它使用相同的 ValidationRule 资源,但它应该可以完成这项工作。
猜你喜欢
  • 2012-05-05
  • 2020-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多