EasyValidation.Core 1.0.0.8

dotnet add package EasyValidation.Core --version 1.0.0.8
                    
NuGet\Install-Package EasyValidation.Core -Version 1.0.0.8
                    
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="EasyValidation.Core" Version="1.0.0.8" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="EasyValidation.Core" Version="1.0.0.8" />
                    
Directory.Packages.props
<PackageReference Include="EasyValidation.Core" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add EasyValidation.Core --version 1.0.0.8
                    
#r "nuget: EasyValidation.Core, 1.0.0.8"
                    
#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.
#:package EasyValidation.Core@1.0.0.8
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=EasyValidation.Core&version=1.0.0.8
                    
Install as a Cake Addin
#tool nuget:?package=EasyValidation.Core&version=1.0.0.8
                    
Install as a Cake Tool

How to use EasyValidation.Core

Step #1 Create your Command

public record PersonCommand(string FirstName, string LastName, int Age, AddressCommand Address1, AddressCommand Address2);
public record AddressCommand(string Street, string City, string Neighborhood);

Step #2 Create your Validator

public class PersonValidator : Validation<PersonCommand>
{
    public override void Validate()
    {
        ForMember(x => x.FirstName)
            .IsRequired()
            .When(x => x is not null && x.Length <= 3).WithMessage("Should has more than 3 chars");

        ForMember(x => x.LastName)
            .IsRequired()
            .When(x => x is not null && x.Length <= 3).WithMessage("Should has more than 3 chars");

        ForMember(x => x.Age)
            .When(x => x < 18).WithMessage("Invalid age");

        AssignMember<AddressValidator, AddressCommand>(x => x.Address1, true);
        AssignMember<AddressValidator, AddressCommand>(x => x.Address2, true);
    }
}

public class AddressValidator : Validation<AddressCommand>
{
    public override void Validate()
    {
        ForMember(x => x.Street)
            .IsRequired()
            .When(x => x is not null && x.Length <= 3).WithMessage("Should has more than 3 chars");

        ForMember(x => x.City)
            .IsRequired()
            .When(x => x is not null && x.Length <= 3).WithMessage("Should has more than 3 chars");

        ForMember(x => x.Neighborhood)
            .IsRequired()
            .When(x => x is not null && x.Length <= 3).WithMessage("Should has more than 3 chars");
    }
}

Step #3 Validate your Command with the Validator

[HttpPost]
public IActionResult Post([FromBody] PersonCommand command)
{
    var validator = new PersonValidator();

    validator.SetValue(command);
    validator.Validate();

    var jsonResult = validator.ResultData.ToJson();

    if (validator.HasErrors)
        return BadRequest(jsonResult);

    return Ok(jsonResult);
}

Sending this JSON

{
  "address1": {
  },
  "address2": {
  }
}

Produces this JSON Result

{
  "Errors": {
    "FirstName": "Is required",
    "LastName": "Is required",
    "Age": "Invalid age",
    "Address1": {
      "Street": "Is required",
      "City": "Is required",
      "Neighborhood": "Is required"
    },
    "Address2": {
      "Street": "Is required",
      "City": "Is required",
      "Neighborhood": "Is required"
    }
  },
  "IsValid": false
}

Custom Validator - Generic

To create a generic method to reuse in many Validators, you can create a static class and method that extends IRuler<T, R> and you'll use the generics like in the samples below.

public static class CommonExtensions
{
    public static IRuler<T, R> IsRequired<T, R>(this IRuler<T, R> ruler, string message = "Is required")
            => ruler.When(x => x is null).WithMessage(message);
}

Custom Validator - Typed

To create a typed method to reuse in many Validators, you can create a static class that extends IRuler<T, R>, but, to type your model property, is required to specify the second generic in the IRuler<,> like in the samples below.

public static class StringExtensions
{
    public static IRuler<T, string> HasMinLenght<T>(this IRuler<T, string> ruler, int minLenght, string message = "Should have more than {0} digits")
            => ruler.When(x => x.Length < minLenght).WithMessage(string.Format(message, minLenght));
}
public static class GuidExtensions
{
    public static IRuler<T, Guid> IsNotEmpty<T>(this IRuler<T, Guid> ruler, string message = "Should not be empty")
        => ruler.When(x => x == Guid.Empty).WithMessage(message);
}

Validator - Custom Validation by command values

public record UserRegistrationCommand(string Email, string Password, string PasswordConfirmation);
public class UserRegistrationValidator : Validation<UserRegistrationCommand>
{
    public override void Validate()
    {
        ForMember(x => x.Email)
            .IsRequired()
            .When(x => x.Length <= 3).WithMessage("Should has more than 3 chars");

        ForMember(x => x.Password)
            .IsRequired()
            .When(x => x.Length <= 3).WithMessage("Should has more than 3 chars");

        ForMember(x => x.PasswordConfirmation)
            .When(x => x.Length <= 3).WithMessage("Should has more than 3 chars");

        string password = GetCommandProperty(x => x.Password);
        string passwordConfirmation = GetCommandProperty(x => x.PasswordConfirmation);

        if(!password.Equals(passwordConfirmation))
            AddError("passwordConfirmation", "Password confirmation is different from password");
    }
}

Author

Made by Guilherme Paschoal (www.linkedin.com/in/guilherme-paschoal/)

GitHub Repository: https://github.com/gabpaschoal/EasyValidation

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.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net6.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on EasyValidation.Core:

Package Downloads
EasyValidation.DependencyInjection

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.