【问题标题】:Validation in MVVM using attributes on properties在 MVVM 中使用属性上的属性进行验证
【发布时间】:2025-11-27 11:05:03
【问题描述】:

在我正在处理的 WPF 项目中,我正在考虑通过视图模型属性上的属性来实现数据验证。

例子:

[RegexConstraint("^[A-Z][a-zA-Z]+$")]
public string Name 
{
    set
    {
         _name = value;
         OnPropertyChanged("Name")
    }
}

我所有的视图模型都继承自一个通用的 ViewModelBase 类,该类实现了 IDataErrorInfo。索引器:

string IDataErrorInfo.this[string columnName]

按名称检索属性(使用反射),

var properties = GetType().GetProperties().Where(p=> p.Name == "someName")

查找所有约束属性...

private static ICollection<IValidator> GetValidations(PropertyInfo property)
{
 return (ValidationAttribute[])property.GetCustomAttributes(typeof(ValidationAttribute), true))
            .Select(va => new AttributeValidator(va)).Cast<IValidator>().ToList();
}

...并执行验证

这似乎可行,但我的问题是 - 有没有人有使用类似技术的经验?这是个坏主意吗?

它确实使我的代码看起来更简洁,并且我避免在我的所有视图模型类中实现 IDataErrorInfo,但另一方面它产生了一个新问题 - 如何构造漂亮的用户消息,当验证逻辑依赖于属性名称/属性名称,而不是使用硬编码的消息——就像我能找到的所有 IDataErrorInfo 示例一样。

总结 - 我的问题是 - 我应该继续走这条路,还是应该使用不同的验证方案?

【问题讨论】:

  • Hy Jakub,我正在尝试在我的 ViewModelBase 上实现 IDataErrorInfo,也许您可​​以与我分享一些技巧?我最困惑的部分是“按名称检索属性(使用反射),找到所有约束属性,并执行验证”
  • Juan Pablo - 我编辑了我的问题并添加了一些代码来帮助您入门。

标签: c# wpf validation mvvm attributes


【解决方案1】:

我已经在几个不同的项目中使用了这种类似的技术,您可以控制大多数 DataAnnotation 属性上的错误消息,以使它们更友好。这是一个完全可行的解决方案,因为我们最近在两个较大的 WPF 项目上这样做了,并且目前正在第三个项目上做同样的事情。现在需要注意的是……我们确实发现自己必须创建许多自定义 DataAnnotation 类来处理许多复杂的业务规则,因此这取决于围绕数据的业务规则的复杂性。如果您主要能够使用开箱即用的 DataAnnotations 在您的应用程序中支持验证,那么您将不会面临同样的挑战。就错误消息而言,您可以在 DataAnnotation 属性上设置命名属性,例如:

    [Required(ErrorMessage = "Title is required.")]

因此,您可以对名为“FirstName”的属性的消息进行美化,您可以在消息中显示为“First Name is required...”。

此外,只要您完成了将基类中的所有内容连接到 IDataErrorInfo 的工作,那么您在 WPF 应用程序中就很出色了。它确实使您的代码更加简洁,并最大限度地减少了您必须编写的内容(如果您需要自定义验证属性,则除外)。

【讨论】:

    【解决方案2】:

    对我来说似乎是一种有效的方法,您仍然可以使用DisplayName 等获得不错的消息。对于完整的消息,您可以拥有一个带有键的属性,然后在资源文件中查找该键。

    【讨论】: