Formidable 2.0.0
Prefix Reserveddotnet add package Formidable --version 2.0.0
NuGet\Install-Package Formidable -Version 2.0.0
<PackageReference Include="Formidable" Version="2.0.0" />
<PackageVersion Include="Formidable" Version="2.0.0" />
<PackageReference Include="Formidable" />
paket add Formidable --version 2.0.0
#r "nuget: Formidable, 2.0.0"
#:package Formidable@2.0.0
#addin nuget:?package=Formidable&version=2.0.0
#tool nuget:?package=Formidable&version=2.0.0
Formidable
Form validation for Blazor, built on FluentValidation — profiles, progressive disclosure, row-stable collections, and one wire format shared by client and server.
I wrote it because the layer between Blazor's EditForm and FluentValidation is one I kept rebuilding by hand, one client form at a time. This is that layer, built once and covered by tests, running a real project's forms today.
What it is
- Draft and Submit from one validator — two lifecycles ship built in: a lenient Draft profile for save-as-you-go, a strict Submit profile for the real thing, both defined once in the same FluentValidation class. Wizard steps and approval stages are custom profiles over that same definition.
- A headless component kit — FormidableForm, FormidableField, FormidableFieldMessage, and FormidableSummary own the EditContext and render the validator's verdict. The library ships no CSS, so the kit drops into a UI library, a design system, or plain HTML.
- One validator, client and server — the same FluentValidation rules run in the browser and again on the server, and the server's ValidationProblemDetails response applies straight into the engine, so a rejected save lights up the exact fields inline.
- Progressive disclosure — a message waits until the visitor has earned it. A field nobody has touched stays silent whatever its rules say; once they have engaged it, it tells them what would actually block the save. A form opened on a saved draft says what those loaded values have already earned in one call. At submit, which errors show is decided by what is on screen at that moment, and a defensive gate catches the case where every failure would otherwise go unseen.
- Warnings and infos that never block: a FluentValidation check followed by .WithSeverity(Severity.Warning) or Severity.Info fails as a warning or an info. Either one shows in the same field messages and summary as an error, with its own CSS class, but only errors stop a submit.
- Collections that keep their errors — a message on a row object belongs to the object, not to the row number, so adding, removing, and reordering rows can never move its error onto the wrong line.
Packages
- Formidable — validation profiles, ProfiledValidator/DraftSubmitValidator, the model validator seam, ValidationIssue/ValidationReport, INormalizableModel. FluentValidation plus Microsoft.Extensions.DependencyInjection.Abstractions, no Blazor dependency.
- Formidable.Blazor — the validation engine (EditContext integration, field registry, validation flows) and the headless component kit.
- Formidable.AspNetCore — minimal-API endpoint filter and MVC action filter, returning ValidationProblemDetails in the same path format the Blazor client consumes.
Quickstart
Install the Blazor package:
dotnet add package Formidable.Blazor
Register it and your FluentValidation validators in Program.cs, using directives included:
using FluentValidation;
using Formidable.Blazor;
builder.Services.AddFormidableBlazor();
builder.Services.AddScoped<IValidator<QuickContact>, QuickContactValidator>();
Add one line to _Imports.razor so the components resolve:
@using Formidable.Blazor
Then wrap a model in FormidableForm and let FormidableInputText, FormidableFieldMessage, and FormidableSummary render the validator's verdict. That is a working form, on any page with an interactive render mode (every page of a standalone WebAssembly app, or a Blazor Web App page carrying @rendermode InteractiveServer, @rendermode InteractiveWebAssembly or @rendermode InteractiveAuto).
In a Blazor Web App (the two-project template), add the same two lines to both Program.cs files: pages prerender and can run on the server, and a validator registered only in the .Client project is invisible there. The quickstart (https://github.com/xfunc-pty-ltd/formidable/blob/main/docs/quickstart.md) has the exact settings per render mode.
Links
The full documentation, the runnable sample app, and every recipe live in the repository:
- Repository: https://github.com/xfunc-pty-ltd/formidable
- Documentation index: https://github.com/xfunc-pty-ltd/formidable/tree/main/docs
- Recipes (behaviour to configuration): https://github.com/xfunc-pty-ltd/formidable/blob/main/docs/recipes.md
- Live demo: https://xfunc-pty-ltd.github.io/formidable/
- Issues and contributions: https://github.com/xfunc-pty-ltd/formidable/blob/main/CONTRIBUTING.md
Licensed under the MIT License.
| Product | Versions 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. |
-
net10.0
- FluentValidation (>= 12.1.1 && < 13.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.0)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Formidable:
| Package | Downloads |
|---|---|
|
Formidable.AspNetCore
ASP.NET Core validation for Formidable on FluentValidation. A minimal-API endpoint filter and an MVC [Validate] attribute run a validation profile and answer an error with a 400 ValidationProblemDetails. Its paths are the ones the Blazor client applies back onto its fields. A Native AOT app validates its minimal APIs with the endpoint filter; [Validate] is for MVC, which Native AOT does not support. |
|
|
Formidable.Blazor
Blazor form validation on FluentValidation: the validation engine and a headless component kit, for WebAssembly and every interactive render mode. Use FormidableForm, or attach to the EditForm and EditContext you already have. A message waits until the visitor has earned it. Warnings never block a submit, and errors stay on their row object when a list reorders. |
GitHub repositories
This package is not used by any popular GitHub repositories.