ArturRios.Validation 2.0.0

dotnet add package ArturRios.Validation --version 2.0.0
                    
NuGet\Install-Package ArturRios.Validation -Version 2.0.0
                    
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="ArturRios.Validation" Version="2.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ArturRios.Validation" Version="2.0.0" />
                    
Directory.Packages.props
<PackageReference Include="ArturRios.Validation" />
                    
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 ArturRios.Validation --version 2.0.0
                    
#r "nuget: ArturRios.Validation, 2.0.0"
                    
#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 ArturRios.Validation@2.0.0
                    
#: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=ArturRios.Validation&version=2.0.0
                    
Install as a Cake Addin
#tool nuget:?package=ArturRios.Validation&version=2.0.0
                    
Install as a Cake Tool

ArturRios.Validation

Docs License: MIT ArturRios.Validation

ArturRios.Validation โ€” a thin, opinionated model-validation layer for .NET built on top of FluentValidation. It wraps FluentValidation's AbstractValidator<T> in a FluentValidator<T> base class that turns validation results into the shapes an application actually consumes: a plain array of error messages, or an ArturRios.Output ProcessOutput / DataOutput<T> envelope โ€” with optional stripping of the quotes and periods that FluentValidation puts in its default messages.

What you get

Type What it does
FluentValidator<T> Base validator: subclass it, declare RuleFor(...) rules in the constructor, get error/Output helpers for free.
IFluentValidator<T> Abstraction over FluentValidator<T> (extends FluentValidation's IValidator<T>) for DI and testing.

Every helper has an asynchronous counterpart taking a CancellationToken. Reach for those whenever the validator declares an asynchronous rule โ€” MustAsync, CustomAsync and the like โ€” because FluentValidation refuses to run one from a synchronous call and throws AsyncValidatorInvokedSynchronouslyException instead.

IFluentValidator<T> is contravariant in T, so a validator for a base type can stand in for one of a derived type. That is also why ValidateAndReturnDataOutput is not on the interface: it returns a DataOutput<T>, which puts T in an output position, and contravariance forbids that. Take the concrete FluentValidator<T> when the validated model has to come back inside the envelope.

classDiagram
    class IValidator~T~ {
        <<interface>>
    }
    class IFluentValidator~T~ {
        <<interface>>
        +ValidateAndReturnErrors(T model, bool removeSpecialChars) string[]
        +ValidateAndReturnProcessOutput(T model, bool removeSpecialChars) ProcessOutput
        +ValidateAndReturnErrorsAsync(T model, bool removeSpecialChars, CancellationToken ct) Task~string[]~
        +ValidateAndReturnProcessOutputAsync(T model, bool removeSpecialChars, CancellationToken ct) Task~ProcessOutput~
    }
    class AbstractValidator~T~ {
        +Validate(T model) ValidationResult
        +ValidateAsync(T model, CancellationToken ct) Task~ValidationResult~
    }
    class FluentValidator~T~ {
        +ValidateAndReturnErrors(T model, bool removeSpecialChars) string[]
        +ValidateAndReturnProcessOutput(T model, bool removeSpecialChars) ProcessOutput
        +ValidateAndReturnDataOutput(T model, bool removeSpecialChars) DataOutput~T~
        +ValidateAndReturnErrorsAsync(T model, bool removeSpecialChars, CancellationToken ct) Task~string[]~
        +ValidateAndReturnProcessOutputAsync(T model, bool removeSpecialChars, CancellationToken ct) Task~ProcessOutput~
        +ValidateAndReturnDataOutputAsync(T model, bool removeSpecialChars, CancellationToken ct) Task~DataOutput~T~~
    }
    IValidator~T~ <|-- IFluentValidator~T~
    AbstractValidator~T~ <|-- FluentValidator~T~
    IFluentValidator~T~ <|.. FluentValidator~T~

Installation

dotnet add package ArturRios.Validation

Targets .NET 10. It pulls in FluentValidation and ArturRios.Output transitively.

Quick start

  1. Define a model and a validator, declaring rules exactly as you would with FluentValidation:
using ArturRios.Validation;
using FluentValidation;

public class Person
{
    public string Name { get; set; } = string.Empty;
    public int Age { get; set; }
}

public class PersonValidator : FluentValidator<Person>
{
    public PersonValidator()
    {
        RuleFor(p => p.Name).NotEmpty();
        RuleFor(p => p.Age).GreaterThan(0);
    }
}
  1. Validate and consume the result in whichever shape you need:
var validator = new PersonValidator();
var person = new Person { Name = "", Age = 0 };

// a) Just the error messages
string[] errors = validator.ValidateAndReturnErrors(person);
// => [ "'Name' must not be empty.", "'Age' must be greater than '0'." ]

// b) Same, but strip the quotes and periods FluentValidation adds
string[] clean = validator.ValidateAndReturnErrors(person, removeSpecialChars: true);
// => [ "Name must not be empty", "Age must be greater than 0" ]

// c) A ProcessOutput envelope (Success is false when there are errors)
ProcessOutput result = validator.ValidateAndReturnProcessOutput(person);

// d) A DataOutput<T> envelope that also carries the validated model back
DataOutput<Person> dataResult = validator.ValidateAndReturnDataOutput(person);

Every helper accepts the optional removeSpecialChars flag, which removes ' and . from the messages, and every one has an asynchronous counterpart taking a CancellationToken:

string[] errors = await validator.ValidateAndReturnErrorsAsync(person, cancellationToken: ct);
ProcessOutput result = await validator.ValidateAndReturnProcessOutputAsync(person, cancellationToken: ct);
DataOutput<Person> data = await validator.ValidateAndReturnDataOutputAsync(person, cancellationToken: ct);

Reach for those whenever the validator declares an asynchronous rule โ€” MustAsync, CustomAsync and the like. FluentValidation refuses to run one from a synchronous call and throws AsyncValidatorInvokedSynchronouslyException instead.

Documentation

Page What's there
Overview Concepts, the full API surface, and end-to-end examples.

Testing

The test suite is xUnit, and every test is named with the Given / When / Then pattern. Every test class carries a Category trait, so the two kinds can be run โ€” and reported โ€” separately:

dotnet test src/ArturRios.Validation.sln --filter "Category=Unit"
dotnet test src/ArturRios.Validation.sln --filter "Category=Functional"

Unit tests exercise the code in isolation against test doubles. Functional tests resolve the validator out of a real service collection, behind both contracts, and drive whole request-shaped flows through it. CI runs the two as separate jobs, and both must pass before a pull request can be merged.

Versioning

Semantic Versioning (SemVer). Breaking changes bump the major version; new non-breaking behavior bumps the minor; fixes bump the patch.

Build, test and publish

Use the official .NET CLI to build, test and publish, and Git for source control. Optional helper toolsets: Dotnet Tools ยท Python Dotnet Tools.

Licensed under the MIT License โ€” see LICENSE.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  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.

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
2.0.0 102 8/24/2026
1.1.0 103 8/19/2026
1.0.0 114 7/17/2026