A powerful code generation system that eliminates duplicate validation logic across frontend and backend applications by defining validation rules once in JSON and generating both C# FluentValidation and TypeScript fluentvalidation-ts validators automatically.
Want to know how I created this project in just a few hours? Read here.
Modern applications require validation at multiple layers:
- Client-side: During user data entry in forms
- Server-side: When data reaches the API/persistence layer
This project solves the problem of duplicate validation logic by providing:
- β Single Source of Truth: Define validation rules once in JSON
- β C# Code Generator: Automatically generates FluentValidation classes for .NET
- β TypeScript Code Generator: Automatically generates fluentvalidation-ts classes for frontend
- β Perfect Consistency: Identical validation behavior across frontend and backend
Create a JSON file for your entity (e.g., rules/User.json):
{
"entity": "User",
"namespace": "MyApp.Models",
"properties": [
{
"name": "Email",
"type": "string",
"rules": [
{ "validator": "NotEmpty", "message": "Email is required" },
{ "validator": "EmailAddress", "message": "Invalid email format" }
]
},
{
"name": "Age",
"type": "number",
"rules": [
{
"validator": "InclusiveBetween",
"parameters": { "min": 18, "max": 120 },
"message": "Age must be between 18 and 120"
}
]
}
]
}dotnet fv-generator generate --input ./rules --output ./Validators --namespace MyApp.ValidatorsGenerated Output (UserValidator.cs):
using FluentValidation;
namespace MyApp.Validators
{
public class UserValidator : AbstractValidator<User>
{
public UserValidator()
{
RuleFor(x => x.Email)
.NotEmpty().WithMessage("Email is required")
.EmailAddress().WithMessage("Invalid email format");
RuleFor(x => x.Age)
.InclusiveBetween(18, 120).WithMessage("Age must be between 18 and 120");
}
}
}npx fv-ts-generator generate --input ./rules --output ./validatorsGenerated Output (UserValidator.ts):
import { Validator } from "fluentvalidation-ts";
export type User = {
email: string;
age: number;
};
export class UserValidator extends Validator<User> {
constructor() {
super();
this.ruleFor("email")
.notEmpty()
.withMessage("Email is required")
.emailAddress()
.withMessage("Invalid email format");
this.ruleFor("age")
.inclusiveBetween(18, 120)
.withMessage("Age must be between 18 and 120");
}
}fluentValidation-cli-claude/
βββ schema/ # JSON schema definition
βββ rules/ # Entity validation definitions
β βββ User.json
β βββ Product.json
β βββ Address.json
βββ src/
β βββ csharp-generator/ # C# code generator CLI
β βββ typescript-generator/ # TypeScript code generator CLI
βββ samples/
β βββ backend/ # ASP.NET Core sample app
β βββ frontend/ # React + TypeScript sample app
βββ docs/ # Comprehensive documentation
- JSON Schema Reference - Complete guide to validation rule syntax
- C# Generator Guide - Using the .NET code generator
- TypeScript Generator Guide - Using the Node.js code generator
- Integration Guide - Integrating validators into your applications
- Architecture - System design and extension points
The system supports 20+ validation rules that work identically in both C# and TypeScript:
| Validator | Description | Example |
|---|---|---|
NotNull |
Value must not be null | "validator": "NotNull" |
NotEmpty |
Value must not be empty/null/whitespace | "validator": "NotEmpty" |
EmailAddress |
Must be valid email format | "validator": "EmailAddress" |
Length |
String length must be in range | "parameters": { "min": 2, "max": 50 } |
MinLength |
Minimum string length | "parameters": { "length": 5 } |
MaxLength |
Maximum string length | "parameters": { "length": 100 } |
Matches |
Must match regex pattern | "parameters": { "pattern": "^[A-Z]+$" } |
GreaterThan |
Numeric value > threshold | "parameters": { "value": 0 } |
LessThan |
Numeric value < threshold | "parameters": { "value": 100 } |
InclusiveBetween |
Value in range (inclusive) | "parameters": { "min": 1, "max": 10 } |
ExclusiveBetween |
Value in range (exclusive) | "parameters": { "min": 0, "max": 100 } |
Every validation rule supports custom error messages:
{
"validator": "NotEmpty",
"message": "Please enter your email address"
}dotnet tool install --global FluentValidation.Generatornpm install -g @fv-cli/typescript-generatorThe samples/ folder contains fully functional examples:
- Backend (ASP.NET Core): Web API with generated validators integrated
- Frontend (React + TypeScript): Form validation using generated validators
See full samples documentation β
Run the samples:
# Backend
cd samples/backend
dotnet run
# Frontend
cd samples/frontend
npm install && npm run dev- β Save Development Time: Write validation rules once, use everywhere
- β Eliminate Bugs: No more frontend/backend validation mismatches
- β Easy Maintenance: Update rules in one place, regenerate code
- β Type Safety: Fully typed validators for both C# and TypeScript
- β Professional UX: Consistent error messages across all platforms
Contributions are welcome! See CONTRIBUTING.md for guidelines.
This project is licensed under the MIT License - see LICENSE file for details.
This project builds upon the excellent work of:
-
FluentValidation by Jeremy Skinner - The powerful, strongly-typed validation library for .NET that has become the industry standard for validation in C#/.NET applications.
-
fluentvalidation-ts by Alex Muench - A TypeScript port of FluentValidation that brings the same elegant validation API to the TypeScript/JavaScript ecosystem.
Without these foundational libraries, this code generation system would not be possible. We are grateful for their contributions to the developer community.
- π Documentation
- π Issue Tracker
- π¬ Discussions
Built with β€οΈ by .NET experts for modern full-stack development