Validon

The What

Validon is a boilerplate validation package that allows validation to be added on

The base Validon package doesn't actually contain any validators itself. All validators are created separately using extension methods.

The How

If you want to get started quickly, then install our Terralect.Validon.General package. This 'General' package contains many common types of validation.


You don't have to use this 'General' package - you can build your own entirely from scratch, using the base Terralect.Validon package.


Validating a single field is done in the following way:


    var someText = "Hello";

    var results = Validate.That(someText)

        .Value(s => s).Contains("bye")

        .Results();


In the above example, the ToString() of the returned validation error would show:

    "The String value of 'Hello' must contain 'bye' (String)"


The ValidationResults object that is returned contains a list of validation errors. You can then use these errors however you prefer. 

Validating Object Collections

A better use of Validon would be to validate a collection of objects. We've created an Animal class to demonstrate this validation usage:


    //Animal(string name, bool isTame, bool hasBeenFed)

   var animals = new List<Animal>

   {

      new Animal("Lion", false, true),

      new Animal("Otter", true, false),

      new Animal("Rabbit", true, true),

      new Animal("Python", true, true)

   };


   var results = Validate.ThatAll(animals)

      .Value(r => r.IsTame).IsTrue()

      .Value(r => r.HasBeenFed).IsTrue()

      .Results();

Nested Collections & Conditions

If you are validating a collection where each item then contains its own nested collection, you can make use of the Inner keyword to target the nested collection. This will then apply validations to that nested collection.


    var results = Validate.ThatAll(people).Inner(p => p.Children)

        .Value(p => p.DateOfBirth).HasValue()

        .Results();



In some instances, you may want to apply validations based on certain conditions. To do this, you append When() after the validation has been specified. You can also chain multiple When()'s if need be.


    var results = Validate.ThatAll(people).Inner(p => p.Children)

        .Value(p => p.DateOfBirth).HasValue().When(p => p.IsStudent)

        .Results();



You can also navigate back from a nested collection, using the BackTo() method.


    var results = Validate.ThatAll(people).Inner(p => p.Children)
       .Value(p => p.DateOfBirth).HasValue()
       .BackTo(people)
       .Value(p => p.IsHungry).HasValue()
       .Results();


Build Your Own Validations

The below extension method demonstrates how to create your own validator. In this case, we've created an IsSafeWithHumans extension method against our Animal class:


   public static class MyValidation

   {

      public static ValidationManager<TInput> IsSafeWithHumans<TInput>(this Validation<TInput, Animal> validation, string customError = null, object tag = null)

      {

            validation.New(input => 

            {

                if (input.IsTame && input.HasBeenFed)

                    return;

                validation.Error("must be tame and fed, to be safe with humans", tag);

            });

            return validation.Manager;

        }

    }



The usage of this would then look as follows:


    var results = Validate.ThatAll(animals)

        .Value(r => r).IsSafeWithHumans()

        .Results();



All of the validations available in the 'General' Validon package were created this way.

More Extensions

In our Terralect.Validon.General  package, we've also added a couple of additional extension methods that filter out either the passed or failed objects. The extension methods have been created against the ValidationResults class. Here is how you would use them:


   var results = Validate.ThatAll(animals)

      .Value(r => r).IsSafeWithHumans()

      .Results();


   var safeAnimals = results.Passed(animals);

   var notSafeAnimals = results.Failed(animals);



Our Passed extension method looks as follows:


   public static List<TInput> Passed<TInput>(this ValidationResults results, IEnumerable<TInput> inputValues)

   {

      var toReturn = new List<TInput>();

      var errors = results.GetErrors();

      foreach (var item in inputValues)

      {

         var hadErrors = errors.Any(e => e.InputValue.Equals(item));

         if (!hadErrors)

            toReturn.Add(item);

         }

      return toReturn;

   }



We encourage the creation of validation packages built against Validon, and sharing them with the community!