使用属性上的属性在MVVM中进行验证

时间:2012-08-03 02:23:43

标签: c# wpf validation mvvm attributes

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

示例:

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

我的所有视图模型都继承自一个实现IDataErrorInfo的常见ViewModelBase类。索引器:

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示例一样。

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

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

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

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

因此,您可以查找名为“FirstName”的属性的消息,您可以在消息中显示为“First Name is required ...”。

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