Validations¶
Flecto provides a built-in validation mechanism to verify that filters are logically consistent before executing a query. Depending on the use case, it can either throw exceptions immediately or return structured errors to support user-facing validation. This adds a layer of safety and prevents malformed or logically incorrect inputs from being processed.
Key principles:¶
- Filters are only validated if provided (i.e., not null), but when present, they are always subjected to built-in logical checks.
- These checks are executed during query construction and use
Ensure-style strict validation by default (throwing exceptions on invalid input). - Validation logic uses the same methods for both internal and external validation:
internally, it throws exceptions on invalid input (e.g., via
Ensure), while externally, it can return structured errors to support user-facing validation. Developers can also inject additional custom validation logic (e.g., business rules) into the same mechanism. - You can also integrate Flecto filters into external validators like FluentValidation.
Built-in behavior¶
Each filter in Flecto has a corresponding validator that performs basic logical consistency checks to ensure correct usage and guard against invalid combinations of values.
Below is a summary of built-in validation logic per filter type:
BoolFilter¶
- Disallows using
EqandNotEqsimultaneously. - If
RequireAtLeastOneis set, requires at least one ofEq,NotEq, orNull. - Invokes
customValidatorif provided and includes its result.
DateFilter¶
- Disallows using
EqandNotEqsimultaneously. - Ensures range boundaries
Gt,Gte,Lt, andLteare logically consistent. - Validates that
InandNotInarrays are not empty if provided. - Invokes
customValidatorif provided.
EnumFilter<T>¶
- Disallows using
EqandNotEqsimultaneously. - Validates that
InandNotInarrays are not empty if provided. - Invokes
customValidatorif provided.
FlagsEnumFilter<T>¶
- Disallows using
EqandNotEqsimultaneously. - Disallows setting both
HasFlagandNotHasFlagat the same time. - Invokes
customValidatorif provided.
GuidFilter¶
- Disallows using
EqandNotEqsimultaneously. - Validates that
InandNotInarrays are not empty if provided. - Invokes
customValidatorif provided.
NumericFilter<T>¶
- Disallows using
EqandNotEqsimultaneously. - Ensures logical consistency of range fields:
Gt,Gte,Lt, andLte. - Validates that
InandNotInarrays are not empty if provided. - Invokes
customValidatorif provided.
PaginationFilter¶
- Validates that
LimitandPageare greater than zero. - If
maxLimitis specified, ensuresLimitdoes not exceed it. - Returns an error if the filter itself is null.
SearchFilter¶
- Requires
Valueto be non-empty and not just whitespace. - Validates that
Valuemeets optionalminLengthandmaxLengthconstraints if provided.
StringFilter¶
- Validates individual string fields (
Eq,NotEq,Contains,StartsWith,EndsWith) for emptiness, length, and optionalcustomValidator. - Validates string arrays (
In,NotIn) for emptiness, length, and optionalcustomArrayValidator. - Honors
allowEmptyStringsto control whether empty strings are permitted. - Applies
maxLengthif provided to restrict string length.
Validation API¶
Flecto provides per-filter validation methods that return structured errors
in the form of (Field, Error) tuples. These are designed for both internal use
(Ensure(...) for exceptions) and user-facing validation (Validate(...)
for result collection).
Each filter type has its own Validate(...) method with a signature tailored to its structure.
All validators:
- Apply built-in logical checks (e.g., Eq + NotEq conflict, range consistency, non-empty arrays).
- Optionally use custom validation logic via
Func<TFilter, (bool IsValid, string? Error)>. - Return a consistent output:
IEnumerable<(string Field, string Error)>.
Example: FlagsEnumFilter¶
public static IEnumerable<(string Field, string Error)> Validate(
FlagsEnumFilter<UserRole>? filter,
Func<FlagsEnumFilter<UserRole>, (bool IsValid, string? ErrorMessage)>? customValidator = null)
Other filters (e.g. SearchFilter, StringFilter) may also accept maxLength, minLength,
allowEmptyStrings, or custom array validators as additional parameters.
Validation Modes¶
There are two usage modes for Flecto's validation system:
1. Internal (Ensure) — always enforced, throws on error¶
Internal validation logic (EnsureValid(...)) runs automatically during query building
and throws immediately on validation failure.
This is useful for internal tools, CLI utilities, or safe programmatic usage or if developer do not use validation for requests.
2. User-facing (Validate) — collects errors for feedback¶
You can manually invoke Validate(...) to get a list of validation results and display them to users:
var errors = FlagsEnumFilterValidator<UserRole>.Validate(filter);
if (errors.Any()) {
return BadRequest(errors);
}
This mode allows API endpoints and UIs to return understandable validation errors instead of throwing.
Example: Add custom rule¶
var errors = FlagsEnumFilterValidator<UserRole>.Validate(
filter,
customValidator: f => (!f.Eq.HasValue || f.Eq.Value.HasFlag(UserRole.Admin), "Only Admins are allowed"));
Example: Use with FluentValidation¶
RuleFor(x => x.Role)
.Must(f => !FlagsEnumFilterValidator<UserRole>.Validate(f).Any())
.WithMessage("Invalid Role filter");
Why it matters¶
Validation gives API developers and consumers predictable behavior, safer filtering, and early failure before querying the database.