C# EntityFramework和DataAnnotation,未显示错误
我正在使用实体框架,并尝试使用数据注释进行验证。我在谷歌上查了几个例子,发现到处都是相同的结构。我遵循了它,但由于某种原因,我的错误没有显示在表单中。我知道,我可能必须使用C# EntityFramework和DataAnnotation,未显示错误,c#,wpf,entity-framework-4,data-annotations,C#,Wpf,Entity Framework 4,Data Annotations,我正在使用实体框架,并尝试使用数据注释进行验证。我在谷歌上查了几个例子,发现到处都是相同的结构。我遵循了它,但由于某种原因,我的错误没有显示在表单中。我知道,我可能必须使用Validator类手动验证属性,但我不知道在哪里进行验证。我知道我可以监听PropertyChanging事件,但它只传递属性的名称,而不传递即将分配的值。有人知道我该怎么解决这个问题吗 提前谢谢 [MetadataType(typeof(Employee.MetaData))] public partial class E
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}" />
<fx:TextBox Width="250" Height="20" CornerRadius="5" BorderThickness="0" MaxLength="50" Text="{Binding Name, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" />
Edit:(根据Rachel的评论实现了IDataErrorInfo类)
公共静态类EntityHelper
{
公共静态字符串ValidateProperty(对象实例,字符串属性名称)
{
PropertyInfo property=instance.GetType().GetProperty(propertyName);
object value=property.GetValue(实例,null);
列出错误=(来自property.GetCustomAttributes(true)中的v.OfType(),其中!v.IsValid(value)选择v.ErrorMessage.ToList();
return(errors.Count>0)?String.Join(“\r\n”,errors):null;
}
}
[元数据类型(typeof(Employee.MetaData))]
公共部分类员工:IDataErrorInfo
{
私有密封类元数据
{
[必需(ErrorMessage=“必须为员工定义名称。”)]
[StringLength(50,ErrorMessage=“名称长度必须小于50个字符。”)]
公共字符串名称{get;set;}
[必需(ErrorMessage=“必须为员工定义用户名。”)]
[StringLength(20,MinimumLength=3,ErrorMessage=“用户名长度必须在3-20个字符之间。”)]
公共字符串用户名{get;set;}
[必需(ErrorMessage=“必须为员工定义密码。”)]
[StringLength(20,MinimumLength=3,ErrorMessage=“密码长度必须在3-20个字符之间。”)]
公共字符串密码{get;set;}
}
公共字符串错误{get{返回字符串.Empty;}}
公共字符串此[字符串属性]
{
获取{return EntityHelper.ValidateProperty(this,property);}
}
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}" />
<fx:TextBox Width="250" Height="20" CornerRadius="5" BorderThickness="0" MaxLength="50" Text="{Binding Name, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" />
我已经成功地实现了类似的场景,我强烈建议您看看它是如何在中实现的。它使用实体框架和WPF的数据注释验证 在使用Entity Framework时,您可能会遇到一个重要问题,即数据注释验证器将忽略您的元数据,直到您在验证之前在代码中的某个位置添加EntityObject的元数据:
TypeDescriptor.AddProviderTransparent(new
AssociatedMetadataTypeTypeDescriptionProvider(typeof(EntityObject)),
typeof(EntityObject));
其他信息:
此外,我认为您的元数据应该是公开的,而不是密封的
以下是DataErrorInfoSupport.cs的摘录,供快速参考:
/// <summary>
/// Gets an error message indicating what is wrong with this object.
/// </summary>
/// <returns>An error message indicating what is wrong with this object. The default is an empty string ("").</returns>
public string Error { get { return this[""]; } }
/// <summary>
/// Gets the error message for the property with the given name.
/// </summary>
/// <param name="memberName">The name of the property whose error message to get.</param>
/// <returns>The error message for the property. The default is an empty string ("").</returns>
public string this[string memberName]
{
get
{
List<ValidationResult> validationResults = new List<ValidationResult>();
if (string.IsNullOrEmpty(memberName))
{
Validator.TryValidateObject(instance, new ValidationContext(instance, null, null), validationResults, true);
}
else
{
PropertyDescriptor property = TypeDescriptor.GetProperties(instance)[memberName];
if (property == null)
{
throw new ArgumentException(string.Format(CultureInfo.CurrentCulture,
"The specified member {0} was not found on the instance {1}", memberName, instance.GetType()));
}
Validator.TryValidateProperty(property.GetValue(instance),
new ValidationContext(instance, null, null) { MemberName = memberName }, validationResults);
}
StringBuilder errorBuilder = new StringBuilder();
foreach (ValidationResult validationResult in validationResults)
{
errorBuilder.AppendInNewLine(validationResult.ErrorMessage);
}
return errorBuilder.ToString();
}
}
//
///获取一条错误消息,指示此对象的错误。
///
///一条错误消息,指示此对象的错误。默认值为空字符串(“”)。
公共字符串错误{get{返回此[“”];}
///
///获取具有给定名称的属性的错误消息。
///
///要获取其错误消息的属性的名称。
///属性的错误消息。默认值为空字符串(“”)。
公共字符串此[string memberName]
{
得到
{
列表验证结果=新列表();
if(string.IsNullOrEmpty(memberName))
{
TryValidateObject(实例,新的ValidationContext(实例,null,null),validationResults,true);
}
其他的
{
PropertyDescriptor property=TypeDescriptor.GetProperties(实例)[memberName];
if(属性==null)
{
抛出新ArgumentException(string.Format(CultureInfo.CurrentCulture,
在实例{1}上找不到指定的成员{0},memberName,instance.GetType());
}
Validator.TryValidateProperty(property.GetValue(实例),
新的ValidationContext(实例,null,null){MemberName=MemberName},validationResults);
}
StringBuilder errorBuilder=新建StringBuilder();
foreach(ValidationResult ValidationResult in validationResults)
{
errorBuilder.AppendInNewLine(validationResult.ErrorMessage);
}
返回errorBuilder.ToString();
}
}
我已经成功地实现了类似的场景,我强烈建议您看看它是如何在中实现的。它使用实体框架和WPF的数据注释验证
在使用Entity Framework时,您可能会遇到一个重要问题,即数据注释验证器将忽略您的元数据,直到您在验证之前在代码中的某个位置添加EntityObject的元数据:
TypeDescriptor.AddProviderTransparent(new
AssociatedMetadataTypeTypeDescriptionProvider(typeof(EntityObject)),
typeof(EntityObject));
其他信息:
此外,我认为您的元数据应该是公开的,而不是密封的
以下是DataErrorInfoSupport.cs的摘录,供快速参考:
/// <summary>
/// Gets an error message indicating what is wrong with this object.
/// </summary>
/// <returns>An error message indicating what is wrong with this object. The default is an empty string ("").</returns>
public string Error { get { return this[""]; } }
/// <summary>
/// Gets the error message for the property with the given name.
/// </summary>
/// <param name="memberName">The name of the property whose error message to get.</param>
/// <returns>The error message for the property. The default is an empty string ("").</returns>
public string this[string memberName]
{
get
{
List<ValidationResult> validationResults = new List<ValidationResult>();
if (string.IsNullOrEmpty(memberName))
{
Validator.TryValidateObject(instance, new ValidationContext(instance, null, null), validationResults, true);
}
else
{
PropertyDescriptor property = TypeDescriptor.GetProperties(instance)[memberName];
if (property == null)
{
throw new ArgumentException(string.Format(CultureInfo.CurrentCulture,
"The specified member {0} was not found on the instance {1}", memberName, instance.GetType()));
}
Validator.TryValidateProperty(property.GetValue(instance),
new ValidationContext(instance, null, null) { MemberName = memberName }, validationResults);
}
StringBuilder errorBuilder = new StringBuilder();
foreach (ValidationResult validationResult in validationResults)
{
errorBuilder.AppendInNewLine(validationResult.ErrorMessage);
}
return errorBuilder.ToString();
}
}
//
///获取一条错误消息,指示此对象的错误。
///
///一条错误消息,指示此对象的错误。默认值为空字符串(“”)。
公共字符串错误{get{返回此[“”];}
///
///获取具有给定名称的属性的错误消息。
///
///要获取其错误消息的属性的名称。
///属性的错误消息。默认值为空字符串(“”)。
公共字符串此[string memberName]
{
得到
{
列表验证结果=新列表();
if(string.IsNullOrEmpty(memberName))
{
Validator.TryValidateO