Yet another validation library : Bolt.Validation

Validation is most common requirement for almost all applications. Asp.Net mvc and Web api using default attribute based model validation. Which is fine for most of the cases. But while developing web api I found that providing error code for each error is very useful for consumer. So the application that consuming my api, can change the workflow of UI based on type of error.

Example of default model validation error response:

{
  "Message": "The request is invalid.",
  "ModelState": {
    "Name": [
      "The Name field is required."
    ],
    "Weight": [
      "The field Weight must be between 0 and 999."
    ]
  }
}

What I like to have:

{
  "errors": [
    {
      "errorCode" : "1001"
      "propertyName" : "Name",
      "errorMessage": "Name is required"
    },
    {
      "errorCode" : "1002",
      "propertyName" : "Email",
      "errorMessage" : "Email is invalid"
    }
  ]
}

As I am using CQS principle in my applications, I use a collection of IValidators that automatically executed before executing command handler. This allow me to add new rule validator if required without changing the command handler class. Make classes simple and loosely coupled.

I just published a nuget package named “Bolt.Validation“. It a small utility to validate an entity fluently. Here is a sample validator class using Bolt.Validator library:

using Bolt.Validation;
using Bolt.Validation.Extensions;
 
public class CreateBookInputValidator : IValidator<Login>
{
    public ValidationResult Validate(Login command)
    {         
        var result = RuleChecker<Login>.For(login)
              .Check(x => x.Email)
                  .ErrorCode("1001")
                  .PropertyName("Email Address")
                  .ErrorMessage("Email address is required")
                  .NotEmpty()
              .Check(x => x.Password)
                  .NotEmpty()
              .Result();
 
        /*
          Json representation of the object "result" will be as below
          {
            isPassed : false,
            errors: [
              {
                errorCode : "1001",
                propertyName: "Email Address",
                errorMessage: "Email address is required"
              },
              {
                errorCode: null,
                propertyName: "Password",
                errorMessage: "Password cannot be null or empty"
              }
            ]
          }
        */
 
        return result.ToValidationResult();
    }
}

The validation library can be used whether you use CQS or not. If you need to write custom validation (not available in library), there are two ways to do this. If your plan to reuse the custom validation in different section then the best way is to write an extension of RuleCheckerUnit. Otherwise you can just use the “That” method which accept a Func that return boolean to indicate whether the rule passed or not. Lets see them in example

Custom validation using extension method.

public static class RuleCheckerAdultValidationExtensions
{
    public static TRuleChecker Adult<TRuleChecker>(this RuleCheckerUnit<TRuleChecker, int> source)
        where TRuleChecker : RuleChecker
    {
        const int minAge = 18;
 
        return source
            .DefaultErrorMessage("{0} must be greater than or equal {1}", source.GetPropertyName(), minAge)
            .That(value => value >= minAge);
    }
}
 
// Sample usage of the new custom validataion
public class CustomerInputValidator
{
    public bool IsValid(Customer customer)
    {
        var result = RuleChecker<Customer>.For(customer)
                      .Check(x => x.Name)
                        .Required()
                      .Check(x => x.Age)
                        .Adult()
                      .Result();
 
        return result.IsPassed;
    }
}

Quick and easy custom validation:

public class CustomerInputValidator
{
    public bool IsValid(Customer customer)
    {
        var result = RuleChecker<Customer>.For(customer)
                      .Check(x => x.Name)
                        .Required()
                      .Check(x => x.Age)
                        .ErrorMessage("Age must be greater than or equal 18")
                        .That(age => age >= 18)
                      .Result();
 
        return result.IsPassed;
    }
}

It is no necessary to use an entity to validate its property. You can validate any value without that value being a property of entity. Here’s an example:

var email = "invalidemailaddress";
var emptyId = Guid.Empty;

new RuleChecker()
    .Check(email)
        .ErrorCode("1001")
        .PropertyName("Email")
        .ErrorMessage("Email is invalid. Please enter a valid email address")
        .Email()
    .Check(emptyId)
        .NotEmpty()
    .Result();

If you like to give this library a try just download the nuget package. That’s all for today. Happy coding:)

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s