Redeon.SuperSiteEngineCore.Web.Eltheon.Core.Features.Validation
Server-side validation and error-handling feature for Eltheon. Ships structured error DTOs, factories, DataAnnotations validation (including nested objects), sync/async validator base classes, and Minimal API endpoint filters that return either ProblemDetails or a consistent ErrorResponse payload. A Swagger operation filter adds application/problem+json content types.
What you get
- DTOs:
ValidationError,ErrorResponse<TError>,ValidationErrorResponse, baseErrorBase, contractIErrorDetail. - Validation helpers: recursive
DataAnnotationValidator,SyncValidatorBase<T>/AsyncValidatorBase<T>, interfacesIValidator<T>,ISyncValidator<T>,IAsyncValidator<T>. - Minimal API integration:
ValidationFilter<T>via.Validate<T>()plusAddEndpointValidation()DI helper. - Swagger:
ProblemDetailsContentTypeOperationFilterto mirrorapplication/jsonasapplication/problem+json.
Usage (Minimal API)
// Program.cs
builder.Services.AddEndpointValidation();
var app = builder.Build();
app.MapPost("/api/things", (ThingDto dto) =>
{
// Only runs when validation passed
return Results.Ok(new { success = true });
}).Validate<ThingDto>(); // DataAnnotations + custom validators
Requests are validated in this order:
- DataAnnotations (including nested objects/collections and
IValidatableObject) - All registered
IValidator<T>implementations
If errors exist:
- If
Accept: application/problem+jsonorX-Use-ProblemDetails: true, a ProblemDetails payload is returned. - Otherwise:
400 BadRequestwithErrorResponse<IErrorDetail> { Errors = [...] }.
Custom validator
public sealed class ThingValidator : ISyncValidator<ThingDto>
{
public bool TryValidate(ThingDto input, List<IErrorDetail> errors)
{
if (string.IsNullOrWhiteSpace(input.Name))
errors.Add(ValidationErrorFactory.Create("NAME_REQUIRED", "Name is required", nameof(input.Name)));
return errors.Count == 0;
}
}
Register via DI:
builder.Services.AddScoped<IValidator<ThingDto>, ThingValidator>();
Swagger setup
services.AddSwaggerGen(o =>
{
o.OperationFilter<ProblemDetailsContentTypeOperationFilter>();
});
Notes
- Target framework: net9.0
- Package reference:
Swashbuckle.AspNetCore.SwaggerGenfor the operation filter. - Feature is versioned independently; bump the csproj
Versionwhen you change its public surface.