Geekeey.Request.Validation (2.0.0)
Installation
dotnet nuget add source --name geekeey --username your_username --password your_token dotnet add package --source geekeey --version 2.0.0 Geekeey.Request.ValidationAbout this package
Lightweight validation library for C# with composable validators, fluent rules, and structured validation results.
Features
- Composable validators: Build validators by inheriting from
Validator<T>and defining rules withRuleForandRuleForEach. - Built-in and custom rules: Use helpers like
NotEmpty,Length,Between, andMatches, or define custom predicates withMust. - Structured validation output: Each failure is returned as a
Problemwith a property path, message, severity, code, and attempted value. - Nested validation: Reuse validators for complex object graphs with
SetValidator, including DI-based resolution. - Configurable paths: Rewrite or remove rule property paths when the reported path should differ from the CLR member path.
Getting Started
Install the NuGet package:
dotnet add package Geekeey.Request.Validation
You may need to add our NuGet feed to your nuget.config this can be done by running the following command:
dotnet nuget add source -n geekeey https://code.geekeey.de/api/packages/geekeey/nuget/index.json
Usage
using Geekeey.Request.Validation;
public sealed record Address(string? Street);
public sealed record CreateUserRequest(
string? Name,
int Age,
Address? Address,
IReadOnlyList<string> Tags);
public sealed class AddressValidator : Validator<Address>
{
public AddressValidator()
{
RuleFor(address => address.Street)
.NotEmpty();
}
}
public sealed class CreateUserRequestValidator : Validator<CreateUserRequest>
{
public CreateUserRequestValidator()
{
RuleFor(request => request.Name)
.NotEmpty()
.Length(2, 100)
.WithCode("NAME_INVALID");
RuleFor(request => request.Age)
.Between(18, 120);
RuleFor(request => request.Address)
.SetValidator(new AddressValidator());
RuleForEach(request => request.Tags)
.NotEmpty()
.WithSeverity(Severity.Warning);
}
}
public sealed record LoginInput(string? Username);
public sealed record LoginRequest(LoginInput Input);
public sealed class LoginInputValidator : Validator<LoginInput>
{
public LoginInputValidator()
{
RuleFor(input => input.Username)
.NotEmpty();
}
}
public sealed class LoginRequestValidator : Validator<LoginRequest>
{
public LoginRequestValidator()
{
RuleFor(request => request.Input)
.WithoutPropertyPath()
.SetValidator(new LoginInputValidator());
}
}
var validator = new CreateUserRequestValidator();
var validation = validator.Validate(new CreateUserRequest(
Name: "",
Age: 16,
Address: new Address(""),
Tags: ["", "admin"]));
foreach (var problem in validation.Problems)
{
Console.WriteLine($"{problem.PropertyPath}: {problem.Message}");
}
The resulting Problem entries include full property paths like Address.Street and Tags[0], making it easy to
surface validation errors back to callers or APIs.
If the validation path needs to differ from the CLR property path, use WithPropertyPath(...) for a custom transform
or WithoutPropertyPath() to drop the current rule path entirely before nested paths are appended.