Contents tagged with Validation
In the past, I had to ask for confirmation before a form was actually submitted; the native way to ask for confirmation is through the browser’s confirm function, which basically displays a user-supplied message and two buttons, OK and Cancel. I wrapped it in a custom reusable validation control, which I am providing here:
A sample usage without any target control might be:
And if you want to specifically validate a control’s value:
When submitting your form, you will get a confirmation prompt similar to this (Chrome):
If you want to validate the maximum number of characters that a string property can take, you might be lured into using MaxLengthAttribute. However, this won’t give you what you want: what this attribute does is, when a model is being generated, it provides the maximum length of the string field in the database, but does not perform any kind of pre-insert or pre-update validation. For that, you need to use StringLengthAttribute. This one is indeed a validation attribute, inheriting from ValidationAttribute, and will be called when EF is about to persist your entity, or when ASP.NET MVC validates a model as a consequence of a post. You can specify both the minimum (MinimumLength) as well as the maximum length (MaximumLength).
Some time ago, I wrote a post on fluent validation for Entity Framework Code First. I think it is a cool concept, and I decided to bring it into NHibernate!
In a nutshell, what I want to be able to achieve is something like this:
You can see that whenever I am about to save (update or insert) some entity of types SomeEntity or AnotherEntity, the fluent validation will occur, and an exception will be thrown if the entity does not pass. Fluent validation consists of one lambda expression – which can have several conditions – applied to an entity and returning a boolean result.
For this, I am using NHibernate’s listeners, and I am adding them dynamically through the ISessionFactory, this way it will apply to all ISessions spawned from it.
Without further delay, here is the code, first, the session factory extensions:
This supports having multiple session factories, and because I am using a GCHandle to wrap them, they are not prevented from being garbage collected.
Next, the class that does the actual validation:
This class holds a collection of validations for an entity type. If the validation fails, it throws an instance of a custom exception class:
Finally, the NHibernate listener:
When we no longer need fluent validation, we can disable it altogether:
Or just for a particular entity:
As always, hope you like it! Do send me your comments!
In a nutshell: Entity Framework Code First (EFCF) validation does not load lazy properties. If any of these properties is marked as required, and it is not loaded, a validation error will occur.
While I understand the reason – imagine you are saving lots of entities where a required property is not loaded, this will cause lots of accesses to the database just for checking that the required entity exists – I think the way things are is not very productive. I hope the Entity Framework team can come up with a solution, I’ll probably propose something myself.
Imagine you have a class model such as:
Say you load a child and make some change:
This will throw a DbEntityValidationException, because EFCF will think that the Child instance does not have its Parent property set. This is really annoying and is the source of great frustration.
Of course, there are some workarounds:
- Explicitly force loading all lazy loaded properties before calling SaveChanges;
- Include all lazy loaded properties in the query (best option), such as:
- Disable validation at all (not recommended):
- Disable lazy loading globally (also not recommended):
- Finally, you can remove the required constraint (not good as well):
Back to Entity Framework Code First (EFCF) validation. On my previous post I mentioned that EFCF did not support fluent validation. While this is true, it isn’t too hard to implement one such mechanism, which is exactly why I am writing this!
I will be using the SavingChanges event to inject the validation logic, which will be implemented by strongly typed delegates. Let’s see some code:
We have an extension method that allows declaring, for an entity type, a validation expression, such as this:
This code can certainly be improved – multiple validations per entity, property-based validations, etc – but I think it is good enough to illustrate my technique.
One final note: the fluent validation will only be fired if the ValidateOnSaveEnabled property is set to true, which is the default.
Most persistence frameworks implement some kind of custom validation of entities before they are sent to the database. By custom I mean something more than just “is not null”, “has XX characters”, etc. This typically includes individual properties as well as validation of the entity as a whole – for example, checking that a property’s value is valid when used together with another property’s value.
Entity Framework Code First is no exception. Out of the box it already offers a number of possibilities for validating entities that cover typical scenarios: validation by attributes or by a validation method. One validation left out is one based on XML, but since Code First doesn’t really use XML, it should be no surprise, and the other is fluent validation, something that really should be supported.
Let’s explore each of these possibilities.
The DbContext class has a virtual method called ShouldValidateEntity that is called for each entity about to be persisted – meaning, inserted or updated –, and, when it returns true – which it does by default – will trigger a call to ValidateEntity, another virtual method. In this method, we have a chance to validate our entities any way we like. An example might be, for instance, checking if the entity to be saved implements IDataErrorInfo and extract validation information from this implementation:
For the validation to occur, the ValidateOnSave property must be true, which it is by default.
Don’t forget to always call the base implementation!
Applying Validation Attributes
Another option, which also applies to ASP.NET MVC validation (see http://weblogs.asp.net/ricardoperes/archive/2012/06/03/asp-net-mvc-validation-complete.aspx) is using validation attributes, that is, attributes that inherit from ValidationAttribute. The base ValidateEntity method of DbContext also checks for these attributes, another reason why you should always call it. Let’s see an example:
You would then apply this to some property in your entity:
The “problem” with this approach is that you must include any assemblies containing these custom validation attributes together with your model. If they are on the same assembly, there’s no problem.
By the way, you can specify multiple validation attributes and you can even apply them to the whole class, not just a property.
Another option, also common to MVC, is having your entities implement IValidatableObject. This interface defines a contract for returning a collection of validation errors for an entity. Here’s a sample implementation:
Handling SavingChanges Event
The “underlying” ObjectContext – which, in fact, is only created if requested – exposes a SavingChanges event which is triggered whenever Entity Framework is about to send changes to the database, typically whenever the SaveChanges method is called. If we handle this event, we can perform our custom validation before our entities are saved, and in case something is wrong we can throw an exception to cancel the saving process:
This has the arguable advantage that it decouples the validation process from the entities and the context themselves.
In case you are using any of these validation techniques, always surround calls to SaveChanges inside a try…catch block and look out for a DbEntityValidationException or your own exception, if you followed the SavingChanges approach. Inside DbEntityValidationException you have an EntityValidationErrors that contains all the details:
Alternatively, you can explicitly call GetValidationErrors and see the collection of errors from all sources, except, of course, SavingChanges, because the context is not actually in the process of saving changes, for all entities currently being tracked by the context.
The order by which these validation processes are applied is:
- ValidationAttribute (from base ValidateEntity)
- IValidatableObject (from base ValidateEntity
- SavingChanges (only if no errors are found)
Pick the one that better suits your needs!
Since this blog started, back in 2008, I wrote a lot of posts. I’d say some are still up to date. I picked a few of them, those I’m more proud of, in no particular order.
ASP.NET Web Forms:
Let me know what you think of them! Are there others you particularly enjoyed?
The Data Annotations framework, introduced in .NET 3.5, and enhanced in .NET 4.0, is likely becoming the basis for attribute-based validation in .NET. I like about it the fact that it is extensible and that it can be (and indeed it is) used in a lot of scenarios, from Silverlight to ASP.NET MVC and Dynamic Data.