【发布时间】:2011-08-04 12:40:12
【问题描述】:
我正在使用实体框架并尝试使用数据注释进行验证。我在谷歌上查了几个例子,到处都发现了相同的结构。我跟着它,但由于某种原因,我的错误没有出现在表格中。我知道,我可能必须使用 Validator 类手动验证属性,但我不知道在哪里做。我知道我可以收听PropertyChanging 事件,但这只会传递属性的名称,而不是即将分配的值。有人知道我该如何解决这个问题吗?
提前致谢。
[MetadataType(typeof(Employee.MetaData))]
public partial class Employee
{
private sealed class MetaData
{
[Required(ErrorMessage = "A name must be defined for the employee.")]
[StringLength(50, ErrorMessage="The name must be less than 50 characters long.")]
public string Name { get; set; }
[Required(ErrorMessage="A username must be defined for the employee.")]
[StringLength(20, MinimumLength=3, ErrorMessage="The username must be between 3-20 characters long.")]
public string Username { get; set; }
[Required(ErrorMessage = "A password must be defined for the employee.")]
[StringLength(20, MinimumLength = 3, ErrorMessage = "The password must be between 3-20 characters long.")]
public string Password { get; set; }
}
}
xaml
<fx:TextBox Width="250" Height="20" CornerRadius="5" BorderThickness="0" MaxLength="50" Text="{Binding Name, UpdateSourceTrigger=PropertyChanged, ValidatesOnExceptions=True, NotifyOnValidationError=True}" />
<fx:TextBox Width="250" Height="20" CornerRadius="5" BorderThickness="0" MaxLength="20" Text="{Binding Username, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}" />
<fx:PasswordBox Width="250" Height="20" CornerRadius="5" BorderThickness="0" MaxLength="20" Password="{Binding Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnExceptions=True, NotifyOnValidationError=True}" />
编辑:(根据 Rachel 的评论实现了 IDataErrorInfo 类)
public static class EntityHelper
{
public static string ValidateProperty(object instance, string propertyName)
{
PropertyInfo property = instance.GetType().GetProperty(propertyName);
object value = property.GetValue(instance, null);
List<string> errors = (from v in property.GetCustomAttributes(true).OfType<ValidationAttribute>() where !v.IsValid(value) select v.ErrorMessage).ToList();
return (errors.Count > 0) ? String.Join("\r\n", errors) : null;
}
}
[MetadataType(typeof(Employee.MetaData))]
public partial class Employee:IDataErrorInfo
{
private sealed class MetaData
{
[Required(ErrorMessage = "A name must be defined for the employee.")]
[StringLength(50, ErrorMessage="The name must be less than 50 characters long.")]
public string Name { get; set; }
[Required(ErrorMessage="A username must be defined for the employee.")]
[StringLength(20, MinimumLength=3, ErrorMessage="The username must be between 3-20 characters long.")]
public string Username { get; set; }
[Required(ErrorMessage = "A password must be defined for the employee.")]
[StringLength(20, MinimumLength = 3, ErrorMessage = "The password must be between 3-20 characters long.")]
public string Password { get; set; }
}
public string Error { get { return String.Empty; } }
public string this[string property]
{
get { return EntityHelper.ValidateProperty(this, property); }
}
xaml
<fx:TextBox Width="250" Height="20" CornerRadius="5" BorderThickness="0" MaxLength="50" Text="{Binding Name, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" />
【问题讨论】:
-
神圣的婚姻!您最好开始使用不同的方法来实现您的验证逻辑,因为当您继续这种方式时,您将走向维护噩梦。为什么不使用 DataAnnotations 或 Validation Application Block 并将其与
DataErrorInfoBase类集成。看一下这种集成的示例here。 -
@Steven 我使用的是EntityFramework,所以生成的实体是从
EntityObject派生的,所以我不能添加另一个基类。您认为任何其他链接可以提供帮助吗?谢谢。 -
见我的update。它描述了如何使用 EF 3.5 执行此操作。
-
@Steven 我尝试了您的链接,但不幸的是我无法理解它。我不知道在哪里定义错误等。我确实听从了您的建议并查看了 DataAnnotations,但我无法让它工作,请参阅编辑后的问题。当我编辑我的文本框以与 ValidationAttributes 冲突时,错误没有出现。
-
您的实体是否实施
IDataErrorInfo?验证需要此接口才能在 WPF 中自动显示
标签: c# wpf entity-framework-4 data-annotations