36

WPF & Entity Framework で DataAnnotations を使用して検証する方法はありますか?

4

7 に答える 7

48

ここで説明されているように、DataAnnotations.Validator クラスを使用できます。

http://johan.driessen.se/archive/2009/11/18/testing-dataannotation-based-validation-in-asp.net-mvc.aspx

ただし、メタデータに「バディ」クラスを使用している場合は、次のように、検証する前にその事実を登録する必要があります。

http://forums.silverlight.net/forums/p/149264/377212.aspx

TypeDescriptor.AddProviderTransparent(
  new AssociatedMetadataTypeTypeDescriptionProvider(typeof(myEntity), 
    typeof(myEntityMetadataClass)), 
  typeof(myEntity));

List<ValidationResult> results = new List<ValidationResult>();
ValidationContext context = new ValidationContext(myEntity, null, null)
bool valid = Validator.TryValidateObject(myEntity, context, results, true);

[Shimmy のコメントに対応するために以下を追加]

上記のロジックを実装するジェネリック メソッドを作成して、任意のオブジェクトから呼び出せるようにしました。

// If the class to be validated does not have a separate metadata class, pass
// the same type for both typeparams.
public static bool IsValid<T, U>(this T obj, ref Dictionary<string, string> errors)
{
    //If metadata class type has been passed in that's different from the class to be validated, register the association
    if (typeof(T) != typeof(U))
    {
        TypeDescriptor.AddProviderTransparent(new AssociatedMetadataTypeTypeDescriptionProvider(typeof(T), typeof(U)), typeof(T));
    }

    var validationContext = new ValidationContext(obj, null, null);
    var validationResults = new List<ValidationResult>();
    Validator.TryValidateObject(obj, validationContext, validationResults, true);

    if (validationResults.Count > 0 && errors == null)
        errors = new Dictionary<string, string>(validationResults.Count);

    foreach (var validationResult in validationResults)
    {
        errors.Add(validationResult.MemberNames.First(), validationResult.ErrorMessage);
    }

    if (validationResults.Count > 0)
        return false;
    else
        return true;
}

検証が必要な各オブジェクトで、このメソッドへの呼び出しを追加します。

[MetadataType(typeof(Employee.Metadata))]
public partial class Employee
{
    private sealed class Metadata
    {
        [DisplayName("Email")]
        [Email(ErrorMessage = "Please enter a valid email address.")]
        public string EmailAddress { get; set; }
    }

    public bool IsValid(ref Dictionary<string, string> errors)
    {
        return this.IsValid<Employee, Metadata>(ref errors);
        //If the Employee class didn't have a buddy class,
        //I'd just pass Employee twice:
        //return this.IsValid<Employee, Employee>(ref errors);
    }
}
于 2010-03-18T03:24:17.357 に答える
4

クレイグの回答に欠けているのは、検証エラーがあるかどうかを実際に確認する方法だと思います。これは、Steve Sanderson によって作成された DataAnnotation 検証ランナーであり、検証チェックを別のレイヤーで実行してからプレゼンテーションを実行したい人向けです ( http://blog.codeville.net/category/xval/、コードはサンプル プロジェクトにあります)。

public static IEnumerable<ErrorInfo> GetErrors(object instance)
{
    var metadataAttrib = instance.GetType().GetCustomAttributes
        (typeof(MetadataTypeAttribute), true).
            OfType<MetadataTypeAttribute>().FirstOrDefault();
    var buddyClassOrModelClass = 
        metadataAttrib != null ? 
        metadataAttrib.MetadataClassType : 
        instance.GetType();
    var buddyClassProperties = TypeDescriptor.GetProperties
        (buddyClassOrModelClass).Cast<PropertyDescriptor>();
    var modelClassProperties = TypeDescriptor.GetProperties
        (instance.GetType()).Cast<PropertyDescriptor>();

    return from buddyProp in buddyClassProperties
           join modelProp in modelClassProperties
               on buddyProp.Name equals modelProp.Name
           from attribute in buddyProp.Attributes.
               OfType<ValidationAttribute>()
           where !attribute.IsValid(modelProp.GetValue(instance))
           select new ErrorInfo(buddyProp.Name, 
               attribute.FormatErrorMessage(string.Empty), instance);
}

私は WPF に精通していません (質問に対するすぐに使える解決策があるかどうかはわかりません) が、おそらくそれを使用できます。

また、彼のブログには、検証ルールを適切に評価できない場合があるというコメントがいくつかありますが、私にとっては失敗したことはありません。

于 2009-11-18T15:48:51.070 に答える
3

WPF アプリケーション フレームワーク (WAF)のBookLibraryサンプル アプリケーションに興味があるかもしれません。WPF および Entity Framework で DataAnnotations を使用するという、まさにあなたが求めていることを行います。

于 2011-02-06T07:28:59.560 に答える
1

同じ質問があり、次のアイデアを見つけました。

于 2010-01-22T23:20:38.647 に答える
0

.NET 4 では、この拡張機能を使用した Entity-Framework で検証がサポートされています。 aspx

DataAnnotations thoを使用しているかどうかはわかりません。

更新
VB.NET で試してみましたが、うまくいきませんでした。C# プロジェクトのみをサポートしていると思います。

于 2010-02-09T19:40:31.357 に答える
0

私は、DataAnnotation 検証コントリビューターを含み、壊れたバインディング (ユーザーが間違った型を入力した場所) をチェックするコントリビューター ベースのバリデーターを作成しました。

http://adammills.wordpress.com/2010/07/21/mvvm-validation-and-type-checking/

于 2010-07-21T22:26:46.700 に答える
0

「バディクラス」をご利用ください。このハウツーの4 番。

于 2009-11-18T14:25:34.803 に答える