CheckValidators 1.0.17

.NET 6.0
There is a newer version of this package available.
See the version list below for details.
dotnet add package CheckValidators --version 1.0.17
NuGet\Install-Package CheckValidators -Version 1.0.17
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CheckValidators" Version="1.0.17" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add CheckValidators --version 1.0.17
#r "nuget: CheckValidators, 1.0.17"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install CheckValidators as a Cake Addin
#addin nuget:?package=CheckValidators&version=1.0.17

// Install CheckValidators as a Cake Tool
#tool nuget:?package=CheckValidators&version=1.0.17

Check Validators (.NET)

Author: Ryan Kueter
Updated: May, 2022

About

Check Validators is a free .NET library, available from the NuGet Package Manager, that provides a simple, elegant, and powerful way to validate and guard your data. You can write your own validation extensions and use them in your project without modifying this library.

Targets:

  • .NET 6

Introduction

Each "Check" contains validation rules that can be chained together using method extension syntax (builder pattern). The If, IfNot, AndIf, AndIfNot, OrIf, and OrIfNot rules allow you to use LINQ to validate the different members of the class, including properties, lists, dictionaries, and other complex types. If an exception is thrown, it will aggrigate a list of errors that can be retrieved with GetErrors() or the errors can be thrown with ThrowErrors(). It also has an IsValid() method that returns true if all conditions were met and false if at least one condition failed.

using CheckValidators;

string? i = null;

var c = new Check<string>(i)
    .IfNull("The string is null.")
    .IfEmptyOrWhitespace("The string is empty.")
    .AndIfNot(s => s.Contains("keyword"), "The string did not contain the keyword.");

// Getting errors
if (c.HasErrors())
{
    foreach (var s in c.GetErrors())
    {
        Console.WriteLine(s);
    }
}

// Throwing errors
if (!c.IsValid())
{
    try
    {
        c.ThrowErrors();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

A Realistic Example

In this example, if the value "MyServiceRequest" is null, no errors will be thrown unless the IfNull rule is applied, and IsValid() will evaluate to false. This example also uses a check statement inside another check statement to validate complex items.

try
{
    new Check<MyServiceRequest>(request)
        .IfNull("The service request cannot be null.")
        .If(p => p.User is null, "The user is invalid.")
        .IfNot(p => p.People.Any(), "The request does not contain any people.")
        // AndIf and AndIfNot only execute when a previous If or IfNot validation succeeds.
        .AndIf(p => p.People.Where(x => new Check<string>(x.Email).IfNull().IfNotEmail().HasErrors()).Any(), "A user has an invalid email.")
        .AndIfNot(p => p.People.Where(x => x.Id > 0).Any(), "One or more ids are invalid.")
        .If(p => new Check<string>(p.Email).IfNull().IfNotEmail().HasErrors(), "An email is invalid.")
        // OrIf and OrIfNot only execute when a previous If or IfNot validation fails.
        .OrIf(p => p.Id is 0, "The user id is invalid.")
        .OrIfNot(p => p.Id > 0, "The user id is invalid.")
        .If(p => p.TimeStamp == default, "Invalid timestamp.")
        .ThrowErrors();
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

AndIf, AndIfNot

The AndIfNot statement will not execute if any previous If rule was invalid. This provides better performance, and prevents unnecessary code execution and unnecessary errors. An example may include checking a child value of a value that was previously determined to be null. The example above checks for an empty list of people. If the list contains people, it will continue to check their email addresses. If the People list is empty, it will skip all following AndIf or AndIfNot statements until it evaluates a new If rule.

OrIf, OrIfNot

OrIf and OrIfNot are the opposite of AndIf and AndIfNot and only execute if a previous If rule fails validation.

Output:
Errors: 1) An email is invalid., 2) A user has an invalid email., 3) Invalid timestamp. (Parameter 'request [MyServiceRequest]')

Extension Methods

You can create your own custom extension methods anywhere in your project to add custom validators that are specific to your needs. If you choose to use a try/catch block, consider throwing the same error in the catch block when using an IfNot, AndIfNot, or OrIfNot rule since they evaluate to false. Avoid throwing the same error in a catch block of an If, AndIf, or OrIf rule since they evaluate to true.

public static partial class CheckValidatorsExtensions
{
    public static Check<List<T>?> IfEmpty<T>(this Check<List<T>?> data, string msg = "")
    {
        if (data.InvalidModel()) { return data; }
        try
        {
            if (!data.Value.Any())
            {
                data.ThrowError(msg, "The list is empty.");
            }
        }
        catch { }
        return data;
    }
}

Supported Datatypes (include but are not limited to)

  • Custom Datatypes
  • Array
  • Dictionary
  • Double
  • Float
  • Int
  • List
  • Long
  • String

Contributions

This project is being developed for free by me, Ryan Kueter, in my spare time. So, if you would like to contribute, please submit your ideas on the Github project page.

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed. 
Compatible target framework(s)
Additional computed target framework(s)
Learn more about Target Frameworks and .NET Standard.
  • net6.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.1.27 76 9/12/2023
1.1.26 80 9/11/2023
1.1.25 79 9/10/2023
1.1.24 90 9/9/2023
1.1.23 83 9/9/2023
1.1.22 75 9/9/2023
1.1.21 85 9/9/2023
1.1.20 79 9/9/2023
1.1.19 320 11/26/2022
1.1.18 363 9/30/2022
1.1.17 392 9/12/2022
1.1.16 364 8/15/2022
1.1.15 380 6/10/2022
1.1.14 372 6/10/2022
1.1.13 381 6/10/2022
1.1.12 378 6/7/2022
1.1.10 382 6/6/2022
1.1.9 384 6/6/2022
1.1.8 376 6/6/2022
1.1.7 363 6/6/2022
1.1.6 383 6/5/2022
1.1.5 370 6/5/2022
1.1.4 376 6/3/2022
1.1.3 385 6/3/2022
1.1.2 390 6/2/2022
1.1.0 410 6/2/2022
1.0.17 408 5/3/2022
1.0.16 408 5/2/2022
1.0.15 415 5/2/2022
1.0.14 409 2/22/2022
1.0.13 391 2/22/2022

Added System.Runtime.CompilerServices.CallerArgumentExpressionAttribute to include the variable name for a more descriptive error.