有没有办法在WPF和&amp ;;中使用DataAnnotations进行验证?实体框架?
答案 0 :(得分:45)
您可以使用DataAnnotations.Validator类,如下所述:
但是如果您使用“伙伴”类作为元数据,则需要在验证之前注册该事实,如下所述:
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);
}
}
答案 1 :(得分:4)
我认为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);
}
我不熟悉WPF(不确定你是否有一些开箱即用的解决方案),但也许你可以使用它。
此外,他的博客上有一些评论说,在某些情况下,它无法正确评估验证规则,但对我来说从未失败过。
答案 2 :(得分:3)
您可能对 WPF Application Framework (WAF) 的 BookLibrary 示例应用感兴趣。它完全符合您的要求:在WPF中使用DataAnnotations&amp;实体框架。
答案 3 :(得分:1)
我有同样的问题并找到了以下想法:
答案 4 :(得分:0)
使用“好友类”。 this how-to中的第4位。
答案 5 :(得分:0)
在.NET 4中,使用此扩展程序在Entity-Framework中有验证支持,请查看:http://blogs.msdn.com/adonet/archive/2010/01/13/introducing-the-portable-extensible-metadata.aspx
我不确定它是否确实使用了DataAnnotations。
<强>更新强>
我用VB.NET尝试过它并没有用,我认为它只支持C#项目。
答案 6 :(得分:0)
我编写了一个基于贡献者的验证器,其中包含一个DataAnnotation验证参与者,还检查了损坏的绑定(用户输入了错误的类型)
http://adammills.wordpress.com/2010/07/21/mvvm-validation-and-type-checking/