2011-08-04 3 views
2

엔티티 프레임 워크를 사용하고 유효성 검사에 데이터 주석을 사용하려고합니다. 나는 구글에서 몇 가지 예를 찾아 보았고 같은 구조를 도처에 발견했다. 나는 그것을 따라 갔지만, 어떤 이유로 나는 나의 오류가 그 형태로 나타나지 않는다. 나는 Validator 클래스를 사용하여 프로퍼티를 수동으로 검증해야 할지도 모르지만 어디서 처리해야하는지 알 수 없다. 나는 PropertyChanging 이벤트를들을 수 있지만 할당하려고하는 값이 아니라 속성의 이름 만 전달한다는 것을 알고 있습니다. 누구든지 내가이 문제를 어떻게 해결할 수 있을지 생각해?EntityFramework 및 DataAnnotations 오류가 표시되지 않습니다.

미리 감사드립니다.

[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; } 
    } 
} 

<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}" /> 

가 편집 XAML :

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 (레이첼의 의견에 따라 IDataErrorInfo 클래스를 구현)

<fx:TextBox Width="250" Height="20" CornerRadius="5" BorderThickness="0" MaxLength="50" Text="{Binding Name, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" /> 
+1

이런 결혼! 이 방법을 계속할 때 유지 보수의 악몽으로 나아갈 것이므로 유효성 검사 논리를 구현하기 위해 다른 접근법을 사용하는 것이 좋습니다. 왜 DataAnnotations 또는 Validation Application Block을 사용하고 DataErrorInfoBase 클래스와 통합할까요? 그러한 통합에 대한 예를 살펴보십시오 (http://bit.ly/crLXAz). – Steven

+0

@Steven EntityFramework를 사용하고 있으므로 생성 된 엔티티는 EntityObject에서 파생되므로 다른 기본 클래스를 추가 할 수 없습니다. 다른 어떤 링크가 도움이 될 것이라고 생각하십니까? 감사. –

+1

내 [업데이트] (http://bit.ly/crLXAz)를 참조하십시오. EF 3.5에서이 작업을 수행하는 방법을 설명합니다. – Steven

답변

0

나는 유사한 시나리오를 성공적으로 구현했으며, 이것이 구현 된 방법을 http://waf.codeplex.com/에서 살펴볼 것을 강력히 제안합니다. Entity Framework 및 WPF에서 데이터 주석 유효성 검사를 사용합니다.

당신이 엔티티 프레임 워크와 함께이 일을 함께해야 할 수 있습니다 한 가지 중요한 문제는 당신이 확인하기 전에 코드에서 어딘가에 EntityObject에 대한 메타 데이터를 추가 할 때까지 데이터 주석 검사기는 메타 데이터를 무시하는 것입니다 :

TypeDescriptor.AddProviderTransparent(new 
    AssociatedMetadataTypeTypeDescriptionProvider(typeof(EntityObject)), 
    typeof(EntityObject)); 

추가 정보 : .NET 4 RTM MetadataType attribute ignored when using Validator

또한 메타 데이터는 공개되어야하며 봉인되지 않아야한다고 생각합니다.

여기에 빠른 참조를 위해, 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(); 
     } 
    } 
관련 문제