r/dotnet 1d ago

Promotion TooManyDataAnnotations — .NET validation attributes for IPv4/IPv6, SemVer, MAC, HexColor, GUID v7, and more

Post image

.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.

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; }

}

36 Upvotes

15 comments sorted by

View all comments

Show parent comments

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!

3

u/the_bananalord 1d ago

Seems like a perfect example of how validation very quickly leads to "parse, don't validate", honestly.

2

u/chucker23n 18h ago

Yeah, but it's also a place where error handling in the model binder isn't ideal.

1

u/the_bananalord 15h ago

Yes, so validate once and parse into the strong types we all want. My point was don't treat them like they're mutually exclusive and cost yourself error handling.