CTP5 provides validation for validator attributes in your classes.
For example, I could apply this attribute to the Customer.CompanyName property:
[MaxLength(20)]
public string CompanyName { get; set; }
How does it get there? If you are using Code First, you can just type it in your class. If you are using code gen, you can modify the T4 template to read the model’s metadata and shove that attribute in there. I actually have an example of this template modification in my book although it writes code for validation, not an attribute, since this feature was not available. (Note: I crossed the last 2 sentences out only because Diego Vega let me know that the validation only works for Code First right now.)
The DbContext class has method, GetValidationErrors which will return any conflicts with your attributes.
Here is that method being used in a test:
public void LongCompanyNameReturnsAValidationError()
{
var customer = new Customer {CompanyName = "thisisa reallylong companyname thatshouldnot validate"};
var context = new AWEntities();
context.Customers.Add(customer);
string message = "";
var error = context.GetValidationErrors().FirstOrDefault().ValidationErrors.FirstOrDefault();
if (error != null)
{ message = error.ErrorMessage; }Assert.IsTrue(message.Contains("maximum") && message.Contains("20") && message.Contains("CompanyName") );
}
}
The actual error message constructed by EF is “The field CompanyName must be a string or array type with a maximum length of ’20’.”
If these errors get through your code, they will be caught by SaveChanges and exposed in the exception.
(Note: Another update from Diego…by default, this will only work with Added and Modified entities. There’s a ShouldValidateEntity setting that I planned to talk about in a later post that you can use to impact this.)
If you aren’t capturing exceptions you’ll get this
The exception is a DbEntityValidationException. You have to drill in to find the actual error.
Why is there a seeming double layer of error collections? They are grouped by entityEntry. So you first have all of the EntityValidationErrors. Then the first one of those is a collection of errors for the ObjectStateEntry that represents the particular Customer instance we are working with. All of the entities being managed by the context are validated before EF attempts to push anything to the database.
Sign up for my newsletter so you don't miss my conference & Pluralsight course announcements!