Contents tagged with Validation

  • ASP.NET Web Forms Prompt Validator

    For those still using Web Forms and Microsoft’s validation framework, like yours truly - and I know you’re out there! -, it is very easy to implement custom validation by leveraging the CustomValidator control. It allows us to specify both a client-side validation JavaScript function and a server-side validation event handler.

    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:

       1: [DefaultProperty("PromptMessage")]
       2: public sealed class PromptValidator : CustomValidator
       3: {
       4:     [DefaultValue("")]
       5:     public String PromptMessage { get; set; }
       6:  
       7:     protected override void OnPreRender(EventArgs e)
       8:     {
       9:         var message = String.Concat("\"", this.PromptMessage, "\"");
      10:  
      11:         if ((this.PromptMessage.Contains("{0}") == true) && (this.ControlToValidate != String.Empty))
      12:         {
      13:             message = String.Concat("String.format(\"", this.PromptMessage, "\", args.Value)");
      14:         }
      15:  
      16:         this.ClientValidationFunction = String.Concat("new Function('sender', 'args', 'args.IsValid = confirm(", message, ")')");
      17:         this.EnableClientScript = true;
      18:  
      19:         base.OnPreRender(e);
      20:     }
      21: }

    A sample usage without any target control might be:

       1: <web:PromptValidator runat="server" PromptMessage="Do you want to submit your data?" ErrorMessage="!"/>

    And if you want to specifically validate a control’s value:

       1: <web:PromptValidator runat="server" PromptMessage="Do you want to accept {0}?" ErrorMessage="!" ControlToValidate="text" ValidateEmptyText="true"/>

    When submitting your form, you will get a confirmation prompt similar to this (Chrome):

    image

    Read more...

  • Entity Framework Pitfalls: String Length Validation

    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).

    Read more...

  • NHibernate Fluent Validation

    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:

       1: var validation = sessionFactory
       2:     .FluentlyValidate()
       3:     .Entity<SomeEntity>(x => x.SomeValue != "", "SomeValue is empty")
       4:     .Entity<AnotherEntity>(x => x.AnotherValue != 0, "AnotherValue is 0");

    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:

       1: public static class SessionFactoryExtensions
       2: {
       3:     internal static readonly IDictionary<GCHandle, FluentValidation> validations = new ConcurrentDictionary<GCHandle, FluentValidation>();
       4:  
       5:     public static FluentValidation FluentlyValidate(this ISessionFactory sessionFactory)
       6:     {
       7:         var validation = GetValidator(sessionFactory);
       8:  
       9:         if (validation == null)
      10:         {
      11:             validation = Register(sessionFactory);
      12:         }
      13:  
      14:         return (validation);
      15:     }
      16:  
      17:     public static void DisableFluentValidation(this ISessionFactory sessionFactory)
      18:     {
      19:         Unregister(sessionFactory);
      20:     }
      21:  
      22:     internal static FluentValidation GetValidator(this ISessionFactory sessionFactory)
      23:     {
      24:         return (validations.Where(x => x.Key.Target == sessionFactory).Select(x => x.Value).SingleOrDefault());
      25:     }
      26:  
      27:     private static void Unregister(ISessionFactory sessionFactory)
      28:     {
      29:         var validation = validations.Where(x => x.Key.Target == sessionFactory).SingleOrDefault();
      30:  
      31:         if (Object.Equals(validation, null) == true)
      32:         {
      33:             validations.Remove(validation);
      34:         }
      35:  
      36:         (sessionFactory as SessionFactoryImpl).EventListeners.FlushEntityEventListeners = (sessionFactory as SessionFactoryImpl).EventListeners.FlushEntityEventListeners.Where(x => !(x is FlushEntityValidatorListener)).ToArray();
      37:     }
      38:  
      39:     private static FluentValidation Register(ISessionFactory sessionFactory)
      40:     {
      41:         var validation = (validations[GCHandle.Alloc(sessionFactory)] = new FluentValidation());
      42:         (sessionFactory as SessionFactoryImpl).EventListeners.FlushEntityEventListeners = (sessionFactory as SessionFactoryImpl).EventListeners.FlushEntityEventListeners.Concat(new IFlushEntityEventListener[] { new FlushEntityValidatorListener() }).ToArray();
      43:         return (validation);
      44:     }
      45: }

    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:

       1: public sealed class FluentValidation
       2: {
       3:     private readonly IDictionary<Type, Dictionary<Delegate, String>> conditions = new ConcurrentDictionary<Type, Dictionary<Delegate, String>>();
       4:     
       5:     public FluentValidation Clear<T>()
       6:     {
       7:         foreach (var type in this.conditions.Where(x => typeof(T).IsAssignableFrom(x.Key)).Select(x => x.Key))
       8:         {
       9:             this.conditions.Remove(type);
      10:         }
      11:         
      12:         return (this);
      13:     }
      14:  
      15:     public FluentValidation Entity<T>(Func<T, Boolean> condition, String message)
      16:     {
      17:         if (this.conditions.ContainsKey(typeof(T)) == false)
      18:         {
      19:             this.conditions[typeof(T)] = new Dictionary<Delegate, String>();
      20:         }
      21:  
      22:         this.conditions[typeof(T)][condition] = message;            
      23:  
      24:         return (this);
      25:     }
      26:  
      27:     public void Validate(Object entity)
      28:     {
      29:         var applicableConditions = this.conditions.Where(x => entity.GetType().IsAssignableFrom(x.Key)).Select(x => x.Value);
      30:  
      31:         foreach (var applicableCondition in applicableConditions)
      32:         {
      33:             foreach (var condition in applicableCondition)
      34:             {
      35:                 var del = condition.Key;
      36:  
      37:                 if (Object.Equals(del.DynamicInvoke(entity), false) == true)
      38:                 {
      39:                     throw (new ValidationException(entity, condition.Value));
      40:                 }
      41:             }
      42:         }
      43:     }
      44: }

    This class holds a collection of validations for an entity type. If the validation fails, it throws an instance of a custom exception class:

       1: [Serializable]
       2: public sealed class ValidationException : Exception
       3: {
       4:     public ValidationException(Object entity, String message) : base(message)
       5:     {
       6:         this.Entity = entity;
       7:     }
       8:  
       9:     public Object Entity
      10:     {
      11:         get;
      12:         private set;
      13:     }        
      14: }

    Finally, the NHibernate listener:

       1: sealed class FlushEntityValidatorListener : IFlushEntityEventListener
       2: {
       3:     #region IFlushEntityEventListener Members
       4:  
       5:     public void OnFlushEntity(FlushEntityEvent @event)
       6:     {
       7:         var validator = @event.Session.SessionFactory.GetValidator();
       8:  
       9:         if (validator != null)
      10:         {
      11:             validator.Validate(@event.Entity);
      12:         }
      13:     }
      14:  
      15:     #endregion
      16: }

    When we no longer need fluent validation, we can disable it altogether:

       1: sessionFactory.DisableFluentValidation();

    Or just for a particular entity:

       1: validation.Clear<SomeEntity>();

    As always, hope you like it! Do send me your comments!

    Read more...

  • Entity Framework Pitfalls: Validation Does Not Load Lazy Properties

    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:

       1: public class Parent
       2: {
       3:     public Int32 ParentId { get; set; }
       4:     public virtual ICollection<Child> Children { get; set; }
       5: }
       6:  
       7: public class Child
       8: {
       9:     public Int32 ChildId { get; set; }
      10:     [Required]
      11:     public virtual Parent Parent { get; set; }
      12: }

    Say you load a child and make some change:

       1: Child c = ctx.Children.Find(1);
       2: c.SomeProperty = "...";
       3:  
       4: ctx.SaveChanges();

    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;
       1: var p = c.Parent;
    • Include all lazy loaded properties in the query (best option), such as:
       1: var c = ctx.Children.Where(x => x.ChildId == 1).Include(x => x.Parent).Single();
    • Disable validation at all (not recommended):
       1: ctx.Configuration.ValidateOnSaveEnabled = false;
    • Disable lazy loading globally (also not recommended):
       1: ctx.Configuration.LazyLoadingEnabled = false;
       2: ctx.Configuration.ProxyCreationEnabled = false;
    • Finally, you can remove the required constraint (not good as well):
       1: public virtual Parent Parent { get; set; }

    Read more...

  • Entity Framework Code First Fluent Validation

    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! Smile

    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:

       1: public static class DbContextExtensions
       2: {
       3:     private static IDictionary<Type, Tuple<Delegate, String>> entityValidations = new ConcurrentDictionary<Type, Tuple<Delegate, String>>();
       4:  
       5:     public static void AddEntityValidation<TEntity>(this DbContext context, Func<TEntity, Boolean> validation, String message) where TEntity : class
       6:     {
       7:         if (context == null)
       8:         {
       9:             throw new ArgumentNullException("context");
      10:         }
      11:  
      12:         if (validation == null)
      13:         {
      14:             throw new ArgumentNullException("validation");
      15:         }
      16:  
      17:         if (String.IsNullOrWhiteSpace(message) == true)
      18:         {
      19:             throw new ArgumentNullException("message");
      20:         }
      21:  
      22:         if (entityValidations.ContainsKey(typeof(TEntity)) == false)
      23:         {
      24:             (context as IObjectContextAdapter).ObjectContext.SavingChanges += delegate
      25:             {
      26:                 if (context.Configuration.ValidateOnSaveEnabled == true)
      27:                 {
      28:                     IEnumerable<TEntity> entities = context.ChangeTracker.Entries<TEntity>().Where(x => x.State == EntityState.Added || x.State == EntityState.Modified).Select(x => x.Entity).ToList();
      29:  
      30:                     foreach (TEntity entity in entities)
      31:                     {
      32:                         String error = ValidateEntity(entity);
      33:  
      34:                         if (String.IsNullOrWhiteSpace(error) == false)
      35:                         {
      36:                             throw (new ValidationException(error));
      37:                         }
      38:                     }
      39:                 }
      40:             };
      41:         }
      42:  
      43:         entityValidations[typeof(TEntity)] = new Tuple<Delegate, String>(validation, message);
      44:     }
      45:  
      46:     private static String ValidateEntity<TEntity>(TEntity entity)
      47:     {
      48:         Type entityType = typeof(TEntity);
      49:  
      50:         if (entityValidations.ContainsKey(entityType) == true)
      51:         {
      52:             Tuple<Delegate, String> entry = entityValidations[entityType];
      53:             Func<TEntity, Boolean> validation = entry.Item1 as Func<TEntity, Boolean>;
      54:  
      55:             if (validation(entity) == false)
      56:             {
      57:                 return (entry.Item2);
      58:             }
      59:         }
      60:  
      61:         return (null);
      62:     }
      63: }

    We have an extension method that allows declaring, for an entity type, a validation expression, such as this:

       1: ctx.AddEntityValidation<SomeEntity>(x => x.SomeProperty != null, "SomeProperty is required");

    The validation will be fired when the SaveChanges method is called and the errors will be encapsulated in a ValidationException:

       1: try
       2: {
       3:     ctx.SaveChanges();
       4: }
       5: catch (ValidationException ex)
       6: {
       7:     //see content of ex.ValidationResult.ErrorMessage
       8: }

    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.

    Read more...

  • Entity Framework Code First Validation

    Introduction

    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.

    Overriding ValidateEntity

    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:

       1: protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry, IDictionary<Object, Object> items)
       2: {
       3:     DbEntityValidationResult result = base.ValidateEntity(entityEntry, items);
       4:     IDataErrorInfo dei = entityEntry.Entity as IDataErrorInfo;
       5:     
       6:     foreach (String propertyName in entityEntry.CurrentValues.PropertyNames)
       7:     {
       8:         String errorMessage = dei[propertyName];
       9:  
      10:         if (String.IsNullOrWhiteSpace(errorMessage) == false)
      11:         {
      12:             result.ValidationErrors.Add(new DbValidationError(propertyName, errorMessage));
      13:         }
      14:     }
      15:  
      16:     return (result);
      17: }

    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:

       1: [Serializable]
       2: [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
       3: public sealed class PositiveAttribute : ValidationAttribute
       4: {
       5:     protected override ValidationResult IsValid(Object value, ValidationContext validationContext)
       6:     {
       7:         Int64 longValue = Convert.ToInt64(value);
       8:  
       9:         if (longValue <= 0)
      10:         {
      11:             return (new ValidationResult("Value cannot be negative or zero"));
      12:         }
      13:  
      14:         return (ValidationResult.Success);
      15:     }
      16: }

    You would then apply this to some property in your entity:

       1: public class MyEntity
       2: {
       3:     [Positive]
       4:     public Int64 MyAlwaysPositiveNumber { get; set; }
       5: }

    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.

    Implementing IValidatableObject

    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:

       1: public class Contract : IValidatableObject
       2: {
       3:     public String Name { get; set; }
       4:     public DateTime StartDate { get; set; }
       5:     public DateTime EndDate { get; set; }
       6:  
       7:     public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
       8:     {
       9:         if (this.StartDate >= this.EndDate)
      10:         {
      11:             yield return (new ValidationResult("The end date is before or the same as the start date", new String[] { "StartDate", "EndDate" }));
      12:         }
      13:     }
      14: }

    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:

       1: (ctx as IObjectContextAdapter).ObjectContext.SavingChanges += ObjectContext_SavingChanges;
       2:  
       3: void ObjectContext_SavingChanges(Object sender, EventArgs e)
       4: {
       5:     ObjectContext octx = sender as ObjectContext;
       6:     IEnumerable<Object> entities = octx.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified).Select(x => x.Entity);
       7:  
       8:     //do custom validation and throw an exception if something wrong is found
       9:  
      10: }

    This has the arguable advantage that it decouples the validation process from the entities and the context themselves.

    Conclusion

    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:

       1: try
       2: {
       3:     ctx.SaveChanges();
       4: }
       5: catch (DbEntityValidationException ex)
       6: {
       7:     foreach (DbEntityValidationResult result in ex.EntityValidationErrors)
       8:     {
       9:         //..
      10:     }
      11: }

    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:

    1. ValidateEntity
    2. ValidationAttribute (from base ValidateEntity)
    3. IValidatableObject (from base ValidateEntity
    4. SavingChanges (only if no errors are found)

    Pick the one that better suits your needs!

    Read more...

  • My All Time Favorite Posts

    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:

    ASP.NET MVC:

    NHibernate:

    .NET:

    Let me know what you think of them! Are there others you particularly enjoyed?

    Read more...

  • ASP.NET MVC Validation Complete

    OK, so let’s talk about validation. Most people are probably familiar with the out of the box validation attributes that MVC knows about, from the System.ComponentModel.DataAnnotations namespace, such as EnumDataTypeAttribute, RequiredAttribute, StringLengthAttribute, RangeAttribute, RegularExpressionAttribute and CompareAttribute from the System.Web.Mvc namespace. All of these validators inherit from ValidationAttribute and perform server as well as client-side validation. In order to use them, you must include the JavaScript files MicrosoftMvcValidation.js, jquery.validate.js or jquery.validate.unobtrusive.js, depending on whether you want to use Microsoft’s own library or jQuery. No significant difference exists, but jQuery is more extensible.

    Read more...