19

WinFormsアプリケーションとEntityFramework5を使用してクライアント側の検証を設定することに興味があります。実行するために実装できるIValidatableObjectインターフェイスと、各エンティティに必要なカスタム検証があることを理解しています。

ただし、WinFormsを使用しているので、ErrorProviderを使用して、ユーザーがフォームに入力するときに検証エラーが発生したときに、ユーザーに適切な通知を表示したいと思います。この機能はIValidatableObjectインターフェイスを使用して実現できますか、それともErrorProviderを正しく機能させるために、エンティティにもIDataErrorInfoインターフェイスを実装する必要がありますか?

これに代わるより良い方法について他に提案があれば、私に知らせてください。私も喜んで調べます。

4

2 に答える 2

10

呼び出された Entity があり、このクラスに検証Carが必要なプロパティが含まれているとします。

public class Car
{
  [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  public int Id { get; set; }

  // Accepted values have to be between 1 and 5.
  public int NeedToBeValidatedRange { get; set; }
}

この例では、Entity と呼ばれるすべてのエンティティの基本クラスを作成する必要があります。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;

/// This is the base class for all entities and it provide a change notfication.
public abstract class Entity : INotifyPropertyChanged
{
  // Event fired when the property is changed!
  public event PropertyChangedEventHandler PropertyChanged;


  /// Called when int property in the inherited class is changed for ther others properties like (double, long, or other entities etc,) You have to do it.
  protected void HandlePropertyChange(ref int value, int newValue, string propertyName)
  {
    if (value != newValue)
    {
      value = newValue;
      this.Validate(propertyName);
      this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
  }

  /// Validate the property 
  /// <returns>
  /// The list of validation errors
  /// </returns>
  private ICollection<ValidationResult> PropertyValidator(string propertyName)
  {
    var validationResults = new Collection<ValidationResult>();
    PropertyDescriptor property = TypeDescriptor.GetProperties(this)[propertyName];

    Validator.TryValidateProperty(
      property.GetValue(this),
      new ValidationContext(this, null, null) { MemberName = propertyName },
      validationResults);

    return validationResults;
  }

  /// Validates the given property and return all found validation errors.
  private void Validate(string propName)
  {
    var validationResults = this.PropertyValidator(propName);
    if (validationResults.Count > 0)
    {
      var validationExceptions = validationResults.Select(validationResult => new ValidationException(validationResult.ErrorMessage));
      var aggregateException = new AggregateException(validationExceptions);
      throw aggregateException;
    }
  }
}

Car クラスを変更すると、次のようになります。

public class Car : Entity
{
  private int id;
  private int needToBeValidatedRange;

  [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  public int Id
  {
    get
    {
      return this.id;
    }
    set
    {
      this.HandlePropertyChange(ref this.id, value, "Id");
    }
  }

  [Range(1, 5)]
  public int NeedToBeValidatedRange
  {
    get
    {
      return this.needToBeValidatedRange;
    }
    set
    {
      this.HandlePropertyChange(ref this.needToBeValidatedRange, value, "NeedToBeValidatedRange ");
    }
  }
}

ユーザー インターフェイスのどこかで、車のエンティティを作成しています。

Car car1 = new Car();
car1.NeedToBeValidatedRange = 3;  // This will work!

Car car2 = new Car();
car2.NeedToBeValidatedRange = 6;  // This will throw ValidationException
  • WPF は非常に優れた ValidationException をサポートしています。
  • Winforms は ValidationException を部分的にサポートしていますが、これを処理する方法は自由です。
于 2013-12-04T16:56:21.617 に答える
5

次の 2 つの選択肢があります。

  • IValidateObject と IdataErrorInfo で poco クラスを拡張し、検証メソッドで ui エラーを発生させます。
  • save changes が呼び出されたときに検証エラーをキャッチし、検証エラーを生成したエンティティ フィールドに応じて ErrorProvider を直接呼び出します。

IValidateObject を使用して poco クラスを拡張し、変更の保存が呼び出されたときに検証エラーを処理する例については、以下を参照してください。

http://msdn.microsoft.com/en-us/data/gg193959.aspx

于 2013-12-01T21:44:08.647 に答える