Is there any way to validate using DataAnnotations in WPF & Entity Framework?
7 Answers
You can use the DataAnnotations.Validator class, as described here:
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
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]
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);
}
}

- 101,809
- 122
- 424
- 632

- 1,947
- 1
- 19
- 18
-
I have a gazillion classes related with MD, do you have any good idea for how to associate it with the MD dynamically, but I want to do it on demand, i.e. only when im going to use this class (or it's validation) and only once. – Shimmy Weitzhandler Aug 10 '10 at 03:07
-
thank you! BTW, no need to mark the dictionary as 'ref', since you're not going to change the reference anyway, just access its properties. – Shimmy Weitzhandler Oct 14 '10 at 06:15
-
@Shimmy - I pass the error dictionary as 'ref' because the IsValid function adds errors to it (initializing first if necessary), and I want to get the results back along with the bool return value. – Jeremy Gruenwald Oct 14 '10 at 17:52
-
I know this is a bit old, but this is pure gold! +1 – MHollis Jul 20 '11 at 06:52
-
1Dictionary is a reference type (not a value type) and is always passed by reference. – JarrettV Aug 10 '11 at 21:58
-
There are two important notes for Silverlight developers here. 1. The technique used in this answer is not supported in Silverlight as the AssociatedMetadataTypeTypeDescriptionProvider class (and others) are not implemented. http://jeffhandley.com/archive/2010/11/16/DataAnnotationsSubset.aspx 2. RIA Services includes validation attributes added to metadata classes in the classes that are generated on the client - which means that this is a non issue on the client when using RIA Services. – Scott Munro Oct 09 '12 at 13:27
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):
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.
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.

- 101,809
- 122
- 424
- 632

- 3,455
- 1
- 28
- 36
-
-
This is an interesting way of accomplishing it - I may revise my version (above) with some of these ideas. – Jeremy Gruenwald Oct 13 '10 at 17:08
You might be interested in the BookLibrary sample application of the WPF Application Framework (WAF). It does exactly what you are asking for: using DataAnnotations in WPF & Entity Framework.

- 6,976
- 1
- 43
- 34
I had the same question and found the following ideas:
- Notification Pattern
- A port of Silverlight's DataForm control to WPF on CodePlex

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

- 125,891
- 12
- 252
- 273
-
The link u provided is not applicaple in WPF, I think I mentioned that in my post. – Shimmy Weitzhandler Jan 23 '10 at 23:40
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
I am not sure if it does use DataAnnotations tho.
UPDATE
I tried it with VB.NET and it didn't work, I think it only supports C# projects.

- 101,809
- 122
- 424
- 632
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)
http://adammills.wordpress.com/2010/07/21/mvvm-validation-and-type-checking/

- 7,719
- 3
- 31
- 47
-
You forget that I was talking about edm designer generated entity objects. – Shimmy Weitzhandler Jul 22 '10 at 04:43