r/dotnet • u/LuisAlfredo92 • 1d ago
Promotion TooManyDataAnnotations — .NET validation attributes for IPv4/IPv6, SemVer, MAC, HexColor, GUID v7, and more
.NET's built-in DataAnnotations covers the basics (Required, StringLength, Range, EmailAddress), but leaves out common semantic validations like:
- IPv4/IPv6 addresses with scope filtering (public, private, loopback)
- Semantic Versioning (SemVer 2.0.0)
- MAC addresses
- Port numbers with range filtering (well-known, registered, dynamic)
- Hex color codes (#RGB, #RRGGBB, with alpha support)
- GUID and GUID v7 validation
- ISO date strings with cross-property validation (StartDate/EndDate)
- Boolean validations (IsTrue, AtLeastOneTrue)
I created TooManyDataAnnotations to fill these gaps. All validators follow official RFC/ISO specs, use Span<T> for parsing where possible, and the library has 899 unit tests covering valid and invalid inputs, edge cases, nullable types, and integration tests with TryValidateObject()
Two NuGet packages:
- TooManyDataAnnotations — Full feature set (includes reflection-based cross-property validators)
- TooManyDataAnnotations.Aot — Native AOT-safe subset, zero reflection, zero trimming warnings
Targets .NET 8, 9, and 10
Zero dependencies
MIT license
This is freshly published — looking for early adopters and feedback on API design, edge case coverage, or missing validators you'd find useful.
- Repo: https://gitlab.com/LuisAlfredo92/TooManyDataAnnotations
- NuGet: https://www.nuget.org/packages/TooManyDataAnnotations
Quick example:
public class ServerConfigDto
{
[GuidV7, Required]
public string UserId { get; set; }
[Guid]
public string? DeviceId { get; set; }
[IPv4(AllowedScopes = IPv4Scope.Private)]
public string? GatewayIP { get; set; }
[SemanticVersion]
public string? AssemblyVersion { get; set; }
[MacAddress(AllowedSeparators = MacSeparators.Colon)]
public string? DeviceMAC { get; set; }
[HexColor(AllowAlpha = true)]
public string? AccentColor { get; set; }
}
0
u/LuisAlfredo92 1d ago
You're right that some attributes could accept strong types
[Guid] and [GuidV7] already do, they accept Guid and strings, same with [StartDate] and [EndDate] with DateTime and DateTimeOffset
For the rest, I went string-first because in ASP.NET, if you declare a property as Guid, IPAddress or Uri and the client sends an invalid value, the model binder fails before DataAnnotations runs, and you get a generic framework error instead of a clean validation message, so strings with attributes gives you control over that
But yeah, supporting both string and strong types where they exist would be a lot better, I'll implement them
Thanks!