Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# EntityFramework和DataAnnotation,未显示错误_C#_Wpf_Entity Framework 4_Data Annotations - Fatal编程技术网

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