Thursday, November 14, 2013

NexPort Campus Moves to Fluent Validation

- 0 comments
Starting with NexPort Campus v5.1 NexPort will support both Castle Validation and Fluent Validation. Castle Validation will be completely phased out by v6.0 and replaced by Fluent Validation.
Fluent Validations are created in a similar manner to an Nhibernate Mapping. Here is an example of a model entity with its mapping and validator.
    using FluentValidation;
    using FluentValidation.Attributes;

    [Validator(typeof(ValidationTestEntityValidator))]
    public class ValidationTestEntity : ModelBase
    {
        public virtual String Phone { get; set; }
        public virtual string CreditCard { get; set; }
        public virtual int NumGreaterThan7 { get; set; }
        public virtual int NumBetween2And27 { get; set; }

    }


    public class ValidationTestEntityMap : FluentNHibernate.Mapping.ClassMap<validationtestentity>
    {
        public const string TableName = "ValidationTestEntity";

        public ValidationTestEntityMap()
        {

            Table(TableName);
            Id(x => x.Id)
                .GeneratedBy.Assigned()
                .UnsavedValue(new Guid("DEADBEEF-DEAD-BEEF-DEAD-BEEFDEADBEEF"));

            Map(e => e.Phone);
            Map(e => e.CreditCard);

            Map(e => e.NumGreaterThan7);
            Map(e => e.NumBetween2And27);


        }
    }

    public class ValidationTestEntityValidator : AbstractValidator<validationtestentity>
    {
        public ValidationTestEntityValidator()
        {
            RuleFor(e => e.CreditCard).CreditCard().NotEmpty();

            RuleFor(e => e.NumGreaterThan7).GreaterThan(7);
            RuleFor(e => e.NumBetween2And27).GreaterThan(2).LessThan(27);

        }
    }

Simple entity validation can be performed anytime by instantiating the validator directly and testing the result:
                var validator = new ValidationTestEntityValidator();
                var result = validator.Validate(entity);
Validation can also be performed anytime by using the Validation Factory:
               var factory = new FluentValidatorFactory();
                var validator = factory.CreateInstance(entity.GetType());
                validator.Validate(entity);
The ValidatorAttribute is applied to the model entity to let the ValidatorFactory know which validator to use.
    
    [Validator(typeof(ValidationTestEntityValidator))]
    public class ValidationTestEntity : ModelBase
    {
When saving or updating an entity to an Nhibernate session there is no need to validate it first. A validation check is performed in the ModelBaseEventListener for all updates and inserts. If the entity fails to validate then a ValidationExcpetion will be thrown. Until v6.0 the ModelBaseEventListener will validate against both the Fluent and Castle validation frameworks.
    using (var session = NHibernateHelper.OpenSession())
            {
                session.BeginTransaction(IsolationLevel.ReadUncommitted);
                var testObj = session.Load<ValidationTestEntity>(id);
                // THIS IS NOT A VALID CREDIT CARD NUMBER
                testObj.CreditCard = "123667";

                // A VALIDATION EXCEPTION WILL BE THROWN BY COMMIT
                session.Transaction.Commit();
                
            }

The ModelBaseEventListener uses the NexPort FluentValidationFactory to create an instance of the proper validator. The factory stores singleton validator references in a ConcurrentDictionary in order to mitigate the performance hit incurred by constructing new validators.

In my next article, I will discuss using Fluent Validation to validate model entities on the client side. In the meantime, please check out the Fluent Validation Documentation.

About NexPort Solutions Group

NexPort Solutions Group is a division of Darwin Global, LLC, a systems and software engineering company that provides innovative, cost-effective training solutions and support for federal, state and local government, as well as the private sector.
[Continue reading...]
 
Copyright © . NexPort Solutions Engineering Blog - Posts · Comments
Theme Template by BTDesigner · Powered by Blogger