.net 使用带有 WPF 和实体框架的 DataAnnotations 验证数据?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1755340/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 13:34:52  来源:igfitidea点击:

Validate data using DataAnnotations with WPF & Entity Framework?

.netwpfentity-frameworkvalidationdata-annotations

提问by Shimmy Weitzhandler

Is there any way to validate using DataAnnotations in WPF & Entity Framework?

有没有办法在 WPF 和实体框架中使用 DataAnnotations 进行验证?

回答by Jeremy Gruenwald

You can use the DataAnnotations.Validator class, as described here:

您可以使用 DataAnnotations.Validator 类,如下所述:

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

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

But if you're using a "buddy" class for the metadata, you need to register that fact before you validate, as described here:

但是,如果您对元数据使用“伙伴”类,则需要在验证之前注册该事实,如下所述:

http://forums.silverlight.net/forums/p/149264/377212.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);

[Added the following to respond to Shimmy's comment]

[添加以下内容以回应 Shimmy 的评论]

I wrote a generic method to implement the logic above, so that any object can call it:

我写了一个通用方法来实现上面的逻辑,这样任何对象都可以调用它:

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

In each object that needs to be validated, I add a call to this method:

在每个需要验证的对象中,我添加了对这个方法的调用:

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

回答by Misha N.

I think that what is missing from Craigs answer is how to actually check if there are validation errors. This is DataAnnotation validation runner written by Steve Sanderson for those who want to run validation check in deferent layer then presentation (http://blog.codeville.net/category/xval/, the code is in example project):

我认为 Craigs 的回答中缺少的是如何实际检查是否存在验证错误。这是由 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);
}

I'm not familiar with WPF (not sure if there is some out-of-the-box solution for you question), but maybe you can use it.

我不熟悉 WPF(不确定是否有一些现成的解决方案可以解决您的问题),但也许您可以使用它。

Also, there are some comments on his blog that in some cases it fails to evaluate validation rule properly but it never failed for me.

此外,在他的博客上有一些评论,在某些情况下,它无法正确评估验证规则,但对我来说从未失败过。

回答by jbe

You might be interested in the BookLibrarysample application of the WPF Application Framework (WAF). It does exactly what you are asking for: using DataAnnotations in WPF & Entity Framework.

您可能对WPF 应用程序框架 (WAF)BookLibrary示例应用程序感兴趣。它完全符合您的要求:在 WPF 和实体框架中使用 DataAnnotations。

回答by Guillaume Gros

I had the same question and found the following ideas:

我有同样的问题,并发现以下想法:

回答by Shimmy Weitzhandler

In .NET 4, there is validation support in Entity-Framework using this extension, check out: http://blogs.msdn.com/adonet/archive/2010/01/13/introducing-the-portable-extensible-metadata.aspx

在 .NET 4 中,Entity-Framework 中使用此扩展提供验证支持,请查看:http: //blogs.msdn.com/adonet/archive/2010/01/13/introducing-the-portable-extensible-metadata。 aspx

I am not sure if it does use DataAnnotations tho.

我不确定它是否确实使用了 DataAnnotations。

UPDATE
I tried it with VB.NET and it didn't work, I think it only supports C# projects.

更新
我用 VB.NET 尝试过,但没有用,我认为它只支持 C# 项目。

回答by Craig Stuntz

Use a "buddy class". Number 4 in this how-to.

使用“伙伴类”。本操作指南中的第 4

回答by Adam Mills

I have written a Contributor based validator which includes a DataAnnotation validation contributor and also checks against broken bindings (where the user has entered incorrect type)

我编写了一个基于 Contributor 的验证器,其中包括一个 DataAnnotation 验证贡献者,并且还检查了损坏的绑定(用户输入了不正确的类型)

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

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