ReHackt.Extensions.Options.Validation
10.1.0
See the version list below for details.
dotnet add package ReHackt.Extensions.Options.Validation --version 10.1.0
NuGet\Install-Package ReHackt.Extensions.Options.Validation -Version 10.1.0
<PackageReference Include="ReHackt.Extensions.Options.Validation" Version="10.1.0" />
<PackageVersion Include="ReHackt.Extensions.Options.Validation" Version="10.1.0" />
<PackageReference Include="ReHackt.Extensions.Options.Validation" />
paket add ReHackt.Extensions.Options.Validation --version 10.1.0
#r "nuget: ReHackt.Extensions.Options.Validation, 10.1.0"
#:package ReHackt.Extensions.Options.Validation@10.1.0
#addin nuget:?package=ReHackt.Extensions.Options.Validation&version=10.1.0
#tool nuget:?package=ReHackt.Extensions.Options.Validation&version=10.1.0
ReHackt.Extensions.Options.Validation
Extends OptionsBuilder<T> and IServiceCollection with nested data annotations validation and eager validation on start.
Get started
Get it on <a href="https://www.nuget.org/packages/ReHackt.Extensions.Options.Validation"><img src="https://www.nuget.org/Content/gallery/img/default-package-icon.svg" height=18 style="height:18px;" /> NuGet</a>
TL;DR
- Create your options class(es)
- Decorate your options with data annotations
- Call
ConfigureAndValidate<T>(Action<T> configureOptions)on yourIServiceCollection
ConfigureAndValidate will configure your options (calling the base Configure method), but will also check that the built configuration respects the data annotations, otherwise an OptionsValidationException (with details) is thrown as soon as the application is started. No misconfiguration surprise at runtime!
Example
// Startup configuration
public void ConfigureServices(IServiceCollection services)
{
services.ConfigureAndValidate<ApplicationOptions>(options => _configuration.Bind(options));
...
}
// Options classes
public class ApplicationOptions
{
[Required]
public EmailOptions Email { get; set; }
public SecurityOptions Security { get; set; }
...
}
public class EmailOptions
{
[Required]
public string Host { get; set; }
[Required]
public int Port { get; set; }
public bool UseSsl { get; set; }
...
}
public class SecurityOptions
{
[Range(8, int.MaxValue, ErrorMessage = "The {0} must be greater than {1}.")]
public int PasswordMinLength { get; set; } = 8;
...
}
If Email:Host is missing from the configuration, the application does not start. The OptionsValidationException holds one failure per error, naming the options class and the full path of the offending member:
DataAnnotation validation failed for 'ApplicationOptions' members: 'Email.Host' with the error: 'The Host field is required.'.
What the recursion covers
The descent walks public instance properties, one declaration per name (the most derived readable one): object properties, and the contents of collection properties, dictionary entries included. It does not explore string or value-type properties, whose annotations are validated at the parent level, static properties, or the primitive and enum items of a collection. Nor does it explore objects of the following types, which carry no annotations: Type and the other reflection types (MemberInfo, ParameterInfo, Module, Assembly), delegates, Uri, X509Certificate certificates and FileSystemInfo. Each object is visited once, which stops cyclic graphs; beyond 32 levels the descent stops, which bounds computed properties that return a new object on each read. Each nested error is prefixed with the property path (Email.Host).
Compared with the .NET validation
Since .NET 8, ValidateDataAnnotations() also validates nested objects, but only the members annotated with [ValidateObjectMembers] or [ValidateEnumeratedItems], and never dictionary entries (dotnet/runtime#97873). ValidateDataAnnotationsRecursively() needs no attribute: it walks the whole graph, dictionaries included. A class annotated for the .NET validation validates the same way with this package.
Use
ServiceCollection extension
ConfigureAndValidate
services.ConfigureAndValidate<TOptions>(configureOptions)
Is syntactic sugar for
services
.AddOptions<TOptions>()
.Configure(configureOptions)
.ValidateDataAnnotationsRecursively()
.ValidateOnStart() // or ValidateEagerly()
.Services
OptionsBuilder extensions
ValidateDataAnnotationsRecursively
This method register this options instance for validation of its DataAnnotations at the first dependency injection. Nested objects are supported.
ValidateOnStart (or ValidateEagerly in previous versions)
This method validates this options instance at application startup rather than at the first dependency injection.
ConfigureAndValidate
optionsBuilder.ConfigureAndValidate<TOptions>(configureOptions)
Is syntactic sugar for
optionsBuilder
.Configure(configureOptions)
.ValidateDataAnnotationsRecursively()
.ValidateOnStart() // or ValidateEagerly()
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. 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 is compatible. 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 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Microsoft.Extensions.Hosting (>= 10.0.13)
- Microsoft.Extensions.Options (>= 10.0.13)
- System.ComponentModel.Annotations (>= 5.0.0)
-
net10.0
- Microsoft.Extensions.Hosting (>= 10.0.13)
- Microsoft.Extensions.Options (>= 10.0.13)
-
net8.0
- Microsoft.Extensions.Hosting (>= 10.0.13)
- Microsoft.Extensions.Options (>= 10.0.13)
-
net9.0
- Microsoft.Extensions.Hosting (>= 10.0.13)
- Microsoft.Extensions.Options (>= 10.0.13)
NuGet packages (6)
Showing the top 5 NuGet packages that depend on ReHackt.Extensions.Options.Validation:
| Package | Downloads |
|---|---|
|
ReHackt.AspNetCore.Authentication
Package Description |
|
|
ReHackt.Email
Provides an email layout to create email templates with Razor and tag helpers, and a service abstraction to send emails. |
|
|
ReHackt.AspNetCore.Builder
Package Description |
|
|
Quantoz.Nexus.Sdk.Shared
Shared files used by sdk's for interacting with the Quantoz Nexus environment. |
|
|
Quantoz.Nexus.Sdk.Token
Sdk for interacting with the Quantoz Nexus token environment. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 10.1.1 | 192 | 10/26/2026 |
| 10.1.0 | 263 | 10/24/2026 |
| 10.0.13 | 1,882 | 10/14/2026 |
| 10.0.12 | 86 | 10/14/2026 |
| 10.0.11 | 14,832 | 8/12/2026 |
| 10.0.1 | 8,500 | 7/30/2026 |
| 10.0.0 | 409,576 | 11/12/2025 |
| 9.0.10 | 12,349 | 10/15/2025 |
| 9.0.9 | 187,428 | 9/9/2025 |
| 9.0.8 | 13,088 | 8/5/2025 |
| 9.0.7 | 2,350 | 7/17/2025 |
| 9.0.6 | 9,848 | 6/11/2025 |
| 9.0.5 | 9,414 | 5/13/2025 |
| 9.0.4 | 21,642 | 4/8/2025 |
| 9.0.3 | 12,719 | 3/11/2025 |
| 9.0.2 | 11,603 | 2/12/2025 |
| 9.0.1 | 6,263 | 1/14/2025 |
| 9.0.0 | 95,777 | 11/12/2024 |
| 8.0.3 | 119,816 | 10/9/2024 |
| 8.0.2 | 832,069 | 2/15/2024 |