JoeDevSharp.Net.Extensions.FormsValidation 1.0.0

dotnet add package JoeDevSharp.Net.Extensions.FormsValidation --version 1.0.0
                    
NuGet\Install-Package JoeDevSharp.Net.Extensions.FormsValidation -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="JoeDevSharp.Net.Extensions.FormsValidation" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="JoeDevSharp.Net.Extensions.FormsValidation" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="JoeDevSharp.Net.Extensions.FormsValidation" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add JoeDevSharp.Net.Extensions.FormsValidation --version 1.0.0
                    
#r "nuget: JoeDevSharp.Net.Extensions.FormsValidation, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#addin nuget:?package=JoeDevSharp.Net.Extensions.FormsValidation&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=JoeDevSharp.Net.Extensions.FormsValidation&version=1.0.0
                    
Install as a Cake Tool

๐Ÿ“˜ Net.Extensions.FormsValidation

Declarative, decoupled, and UI-agnostic validation framework for .NET applications


๐ŸŽฏ Goal

Net.Extensions.FormsValidation decouples validation logic from UI components, offering a fluent, reusable, and strongly-typed way to define validation rules for any data type. It's compatible with WinForms, WPF, Blazor, ASP.NET Core, Maui, and any other .NET UI or data-based technology.


๐Ÿงฑ Architecture

Component Description
FormValidator Main coordinator that registers fields and triggers validation.
Validator<T> Core component to compose rules for type T.
ValidationResult Represents the result of a validation with severity and message.
ValidationRule<T> Individual rule implementing logic for a Validator<T>.
Extensions (*.Extensions) Extension methods providing ready-to-use rules.

๐Ÿงช Usage Example

var formValidator = new FormValidator();

var nameValidator = Validator<string>
    .Create()
    .Required("Name is required")
    .MinLength(3, "Minimum 3 characters")
    .MaxLength(50);

var ageValidator = Validator<int>
    .Create()
    .GreaterThan(17, "Must be an adult")
    .LessThanOrEqualTo(99);

formValidator.AddFieldValidator("Name", () => nameInput.Text, nameValidator);
formValidator.AddFieldValidator("Age", () => int.Parse(ageInput.Text), ageValidator);

var result = formValidator.Validate();

if (!result.IsValid)
{
    Console.WriteLine(result.Message); // Or display it in the UI
}

๐Ÿงฉ Available Extensions

๐Ÿ“„ Text (string)

  • .Required()
  • .MinLength(int) / .MaxLength(int) / .Length(min, max)
  • .Email()
  • .UrlRule()
  • .StartsWith(), .EndsWith(), .Contains(), .NotContains()
  • .Regex()

๐Ÿ”ข Numbers (int, double, etc.)

  • .GreaterThan(), .GreaterThanOrEqualTo()
  • .LessThan(), .LessThanOrEqualTo()
  • .EqualTo(), .NotEqualTo()
  • .Range(min, max)

๐Ÿ•’ Dates (DateTime)

  • .PastDateRule()
  • .FutureDateRule()
  • .DateRange(min, max)

๐Ÿงบ Collections (ICollection<object>, lists, arrays)

  • .NotEmpty()
  • .MinCount(int) / .MaxCount(int)
  • .AnyMatch(predicate) / .AllMatch(predicate)

โœ… ValidationResult

Simple class representing the result of a validation:

public class ValidationResult
{
    public bool IsValid => Severity == null;
    public ValidationSeverity? Severity { get; }
    public string Message { get; }

    public static ValidationResult Success() => new ValidationResult();
    public static ValidationResult Fail(string message, ValidationSeverity severity = ValidationSeverity.Error)
        => new ValidationResult(severity, message);
}

๐Ÿ”Œ UI Integration (Examples)

WinForms

var validator = new FormValidator();
var emailValidator = Validator<string>
    .Create()
    .Required("Email is required")
    .Email("Invalid email");

validator.AddFieldValidator("Email", () => emailTextBox.Text, emailValidator);

var result = validator.Validate();
if (!result.IsValid)
{
    MessageBox.Show(result.Message);
}

Blazor

<EditForm OnValidSubmit="Validate">
    <InputText @bind-Value="Model.Email" class="form-control" />
    <ValidationMessage For="@(() => Model.Email)" />
    <button type="submit">Validate</button>
</EditForm>

@if (!string.IsNullOrEmpty(ErrorMessage))
{
    <p class="text-danger">@ErrorMessage</p>
}

@code {
    private FormValidator validator = new();
    private string ErrorMessage = string.Empty;
    private MyModel Model = new();

    protected override void OnInitialized()
    {
        var emailValidator = Validator<string>
            .Create()
            .Required("Email is required")
            .Email("Invalid email format");

        validator.AddFieldValidator("Email", () => Model.Email, emailValidator);
    }

    void Validate()
    {
        var result = validator.Validate();
        ErrorMessage = result.IsValid ? string.Empty : result.Message;
    }

    public class MyModel
    {
        public string Email { get; set; } = string.Empty;
    }
}

WPF

var validator = new FormValidator();
var nameValidator = Validator<string>
    .Create()
    .Required("Name is required")
    .MinLength(2);

validator.AddFieldValidator("Name", () => NameTextBox.Text, nameValidator);

var result = validator.Validate();
if (!result.IsValid)
{
    MessageBox.Show(result.Message);
}

ASP.NET Core (MVC)

public class MyModel
{
    public string Email { get; set; } = string.Empty;
}

[HttpPost]
public IActionResult Submit(MyModel model)
{
    var validator = new FormValidator();
    var emailValidator = Validator<string>
        .Create()
        .Required("Email is required")
        .Email("Invalid email");

    validator.AddFieldValidator("Email", () => model.Email, emailValidator);

    var result = validator.Validate();
    if (!result.IsValid)
    {
        ModelState.AddModelError("Email", result.Message);
        return View(model);
    }

    // Proceed normally
    return RedirectToAction("Success");
}

๐Ÿงฑ Key Benefits

  • โœ… Fully decoupled from the UI
  • ๐Ÿงช Composable and reusable validations
  • ๐Ÿ”„ Easy to integrate with any architecture (MVVM, MVP, etc.)
  • โ™ป๏ธ Reusable in services, APIs, and business logic

๐Ÿšง Roadmap

  • Async validation support
  • Sectioned/grouped field validation
  • Error message localization
  • Direct support for IValidationAttribute

๐Ÿ—‚๏ธ Main Namespaces

  • Net.Extensions.FormsValidation
  • Net.Extensions.FormsValidation.Extensions
  • Net.Extensions.FormsValidation.Rules
  • Net.Extensions.FormsValidation.Enums

๐Ÿ“ฆ Installation (coming soon to NuGet)

dotnet add package JoeDevSharp.Net.Extensions.FormsValidation

Built for developers seeking modern, fluent, and decoupled validation in any .NET stack.


Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 358 6/23/2025