Есть ли способ проверить использование DataAnnotations в WPF и Entity Framework?
Проверять данные с помощью DataAnnotations с помощью WPF и Entity Framework?
Ответ 1
Вы можете использовать класс 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 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);
}
}
Ответ 2
Я думаю, что то, что отсутствует в ответе Craigs, - это как проверить, есть ли ошибки проверки. Это бегун проверки правильности DataAnnotation, написанный Стивом Сандерсоном для тех, кто хочет запустить проверку проверки в слое deferent, затем презентацию (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 (не уверен, есть ли какое-то готовое решение для вашего вопроса), но, возможно, вы можете его использовать.
Кроме того, есть некоторые комментарии к его блогу, что в некоторых случаях он не может правильно оценить правило проверки, но для меня это никогда не сработало.
Ответ 3
Вам может быть интересно использовать приложение BookLibrary WPF Application Framework (WAF). Он делает именно то, о чем вы просите: использование DataAnnotations в WPF и Entity Framework.
Ответ 4
У меня был такой же вопрос, и я нашел следующие идеи:
- Шаблон уведомления
- Порт управления Silverlight DataForm для WPF на CodePlex
Ответ 5
Используйте "класс приятеля". Номер 4 в это руководство.
Ответ 6
В .NET 4 поддерживается поддержка валидации в Entity-Framework с помощью этого расширения, проверьте: http://blogs.msdn.com/adonet/archive/2010/01/13/introducing-the-portable-extensible-metadata.aspx
Я не уверен, что он использует DataAnnotations tho.
UPDATE
Я попробовал это с VB.NET, и это не сработало, я думаю, что он поддерживает только проекты С#.
Ответ 7
Я написал валидатор, основанный на Contributor, который включает в себя вкладчика для проверки данных DataAnnotation, а также проверяет неработающие привязки (где пользователь вводил неверный тип)
http://adammills.wordpress.com/2010/07/21/mvvm-validation-and-type-checking/