![]() |
VOOZH | about |
dotnet add package Qowaiv.Validation.DataAnnotations --version 6.0.0
NuGet\Install-Package Qowaiv.Validation.DataAnnotations -Version 6.0.0
<PackageReference Include="Qowaiv.Validation.DataAnnotations" Version="6.0.0" />
<PackageVersion Include="Qowaiv.Validation.DataAnnotations" Version="6.0.0" />Directory.Packages.props
<PackageReference Include="Qowaiv.Validation.DataAnnotations" />Project file
paket add Qowaiv.Validation.DataAnnotations --version 6.0.0
#r "nuget: Qowaiv.Validation.DataAnnotations, 6.0.0"
#:package Qowaiv.Validation.DataAnnotations@6.0.0
#addin nuget:?package=Qowaiv.Validation.DataAnnotations&version=6.0.0Install as a Cake Addin
#tool nuget:?package=Qowaiv.Validation.DataAnnotations&version=6.0.0Install as a Cake Tool
Provides an data annotations based implementation of the Qowaiv.Validation.Abstractions.IValidator
and data annotation attributes.
The AnnotatedModelValidator validates a model using its data annotations.
It returns a Result<TModel> of the validated model:
var validator = new AnnotatedModelValidator<SomeModel>();
Result<SomeModel> result = validator.Validate(model);
Qowaiv.Validation.DataAnnotations.ValidationMessage inherits Microsoft's
ValidationResult, and implements Qowaiv.Validation.Abstractions.IValidationMessage.
This allows the creation of messages with different severities:
var none = ValidationMessage.None; // returns null, but for telling the story ValidationMessage.None is preferred.
var info = ValidationMessage.Info(message, args);
var warn = ValidationMessage.Warning(message, args);
var error = ValidationMessage.Error(message, args);
The required modifier is available since C# 11.
When a model has a property with a required modifier, it is considered being
decorated with a [Required] attribute via the required modifier when the
property:
?) annotationSo in this example:
public class Model
{
public required string RequiredByModifier { get; init; }
public required string? Optional { get; init; }
[Required(AllowEmptyStrings = true)]
public required string AllowStringEmpty {get; init; }
}
The first property is considered required by the AnnotatedModelValidator, and
the second one is considered optional. The third one is also considered required,
but via the attribute it was decorated with, not because of the required modifier.
Multiple [System.ComponentModel.DataAnnotations.Validation] attributes can be
used to decorate models.
The [Required] attribute does not work for value types. The [Mandatory]
attribute does. The default value of the struct is not valid. It also is not
valid for the Unknown value, unless that is explicitly allowed.
public class Model
{
[Mandatory(AllowUnknownValue = true)]
public EmailAddress Email { get; init; }
[Mandatory()]
public string SomeString { get; init; }
}
The [Required] attribute does not work (well) for collections. The [Any]
attribute does. It is only valid if the collection contains at least one item.
public class Model
{
[Any()]
public List<int> Numbers { get; init; }
}
The [Allowed<TValue>] attribute allows to define a subset of allowed values. It
supports type converters to get the allowed values based on a primitive value.
public class Model
{
[Allowed<Country>("DE", "FR", "GB")]
public Country CountryOfBirth { get; init; }
}
The [Forbidden<TValue>] attribute allows to define a subset of forbidden values. It
supports type converters to get the forbidden values based on a primitive value.
public class Model
{
[Forbidden<Country>("US", "IR")]
public Country CountryOfBirth { get; init; }
}
The [DefinedOnly<TEnum>] attribute limits the allowed values to defined
enums only. By default it supports all possible combinations of defined enums
when dealing with flags, but that can be restricted by setting
OnlyAllowDefinedFlagsCombinations to true.
public class Model
{
[DefinedOnly<SomeEnum>(OnlyAllowDefinedFlagsCombinations = false)]
public SomeEnum CountryOfBirth { get; init; }
}
The [InFuture] attributes requires the DateTime, DateTimeOffset, Date,
DateOnly, or Year value to be in the future. The current time is resolved
using Qowaiv.Clock.UtcNow().
public class Model
{
[InFuture]
public DateOnly? ExpiryDate { get; init; }
}
The [InPast] attributes requires the DateTime, DateTimeOffset, Date,
DateOnly, or Year value to be in the past. The current time is resolved
using Qowaiv.Clock.UtcNow().
public class Model
{
[InPast]
public DateOnly DateOfBirth { get; init; }
}
The [InRange<TValue>] attribute the allowed values to the specified range.
This attribute is simliar to Microsoft's [Range](https://learn.microsoft.com/dotnet/api/system.componentmodel.dataannotations.rangeattribute).
The [Items<TValidator>] attribute to define a validation attribute to apply
on all items of a collection. This is useful in multiple cases:
public class Model
{
[Items<Mandatory>] // ensures none of the items is null or empty
public string[] Names { get; init; } = [];
[Items<Allowed<int>(42, 2017)] // ensures that all items have either the value 42 or 2017.
public int[] Numbers { get; init; } = [];
}
By defining either ErrorMessage or both ErrorMessageResourceName and ErrorMessageResourceType,
those values are set to the TValidator allowing full control of the error message generation.
The [IsFinite] attribute validates that the floating point value of the field
represents a finite (e.a. not NaN, or infinity).
public class Model
{
[IsFinite]
public double Number { get; init; }
}
The [SkipValidation] attribute allows to skip the validation of property or
type.
[SkipValidation]
public class Model
{
[SkipValidation]
public double Number { get; init; }
}
The [MultipleOf] attribute validates that the value of a field is a multiple
of the specified factor.
public class Model
{
[MultipleOf(0.001)]
public Amount Total { get; init; }
}
The [NotInFuture] attributes requires the DateTime, DateTimeOffset, Date,
DateOnly, or Year value not to be in the future. The current time is resolved
using Qowaiv.Clock.UtcNow().
public class Model
{
[InFuture]
public DateTime CreationTime { get; init; }
}
The [NotInPast] attributes requires the DateTime, DateTimeOffset, Date,
DateOnly, or Year value not to be in the past. The current time is resolved
using Qowaiv.Clock.UtcNow().
public class Model
{
[InPast]
public DateOnly Start { get; init; }
}
The [NotUnknown] attribute indicates that the field does not allow the unknown value.
public class Model
{
[NotUnknown]
public EmailAddress Address { get; init; }
}
The [Optional] attribute indicates explicitly that a field is optional.
public class Model
{
[Optional]
public string? Message { get; init; }
}
The [Unique<Value>] attribute validates that all items of the collection are
distinct. If needed, a custom IEqualityComparer<Value> comparer can be defined.
public class Model
{
[Unique<int>(typeof(CustomEqualityComparer))]
public IEnumerable<int> Numbers { get; init; }
}
The [Validates] attribute is designed to help the QW0102
to report on misusage of the attribute. By decorating an [Validation] attribute
the analyzer knows on which member types the attribute can be set.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 net5.0 was computed. net5.0-windows net5.0-windows was computed. net6.0 net6.0 was computed. net6.0-android net6.0-android was computed. net6.0-ios net6.0-ios was computed. net6.0-maccatalyst net6.0-maccatalyst was computed. net6.0-macos net6.0-macos was computed. net6.0-tvos net6.0-tvos was computed. net6.0-windows net6.0-windows was computed. net7.0 net7.0 was computed. net7.0-android net7.0-android was computed. net7.0-ios net7.0-ios was computed. net7.0-maccatalyst net7.0-maccatalyst was computed. net7.0-macos net7.0-macos was computed. net7.0-tvos net7.0-tvos was computed. net7.0-windows net7.0-windows was computed. net8.0 net8.0 is compatible. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 was computed. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 netcoreapp2.0 was computed. netcoreapp2.1 netcoreapp2.1 was computed. netcoreapp2.2 netcoreapp2.2 was computed. netcoreapp3.0 netcoreapp3.0 was computed. netcoreapp3.1 netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 netstandard2.0 is compatible. netstandard2.1 netstandard2.1 was computed. |
| .NET Framework | net461 net461 was computed. net462 net462 was computed. net463 net463 was computed. net47 net47 was computed. net471 net471 was computed. net472 net472 was computed. net48 net48 was computed. net481 net481 was computed. |
| MonoAndroid | monoandroid monoandroid was computed. |
| MonoMac | monomac monomac was computed. |
| MonoTouch | monotouch monotouch was computed. |
| Tizen | tizen40 tizen40 was computed. tizen60 tizen60 was computed. |
| Xamarin.iOS | xamarinios xamarinios was computed. |
| Xamarin.Mac | xamarinmac xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos xamarinwatchos was computed. |
Showing the top 1 NuGet packages that depend on Qowaiv.Validation.DataAnnotations:
| Package | Downloads |
|---|---|
|
Qowaiv.Validation.TestTools
Qowaiv Validation supports a generic interface for (domain) model validation. |
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 6.0.0 | 5,060 | 5/21/2026 |
| 5.0.1 | 26,582 | 2/23/2026 |
| 5.0.0 | 7,468 | 1/19/2026 |
| 4.0.2 | 27,486 | 9/19/2025 |
| 4.0.1 | 10,726 | 7/25/2025 |
| 4.0.0 | 11,236 | 6/5/2025 |
| 3.0.0 | 34,539 | 11/19/2024 |
| 2.0.0 | 21,398 | 6/28/2024 |
| 1.4.0 | 27,185 | 8/4/2023 |
| 1.3.0 | 35,858 | 3/7/2023 |
| 1.0.1 | 15,773 | 11/8/2022 |
| 1.0.0 | 5,868 | 7/12/2022 |
| 0.2.4 | 4,271 | 6/29/2022 |
| 0.2.3 | 643 | 6/28/2022 |
| 0.2.2 | 6,316 | 5/13/2022 |
| 0.2.1 | 11,026 | 4/13/2022 |
| 0.2.0 | 7,817 | 12/31/2021 |
| 0.1.1 | 13,754 | 9/10/2021 |
| 0.1.0 | 790 | 8/31/2021 |
| 0.0.4 | 2,703 | 7/2/2021 |
v6.0.0
- Add [NotUnknown] to indicate that the unknown value is not allowed.
- Update to Qowaiv v8.0.0. (BREAKING)
v5.0.1
- Validation attributes support both ErrorMessage as ErrorMessageResourceName and ErrorMessageResourceType. (BUG)
v5.0.0
- Add .NET 10.0 target.
- Drop .NET 5.0, NET6.0, NET7.0 targets. (BREAKING)
v4.0.3
- Type conversions done by DataAnotations are culture independent. (BUG)
v4.0.2
- Support custom TypeConverters for [Allowed<T>] and [Forbidden<T>].
- Support System.Net.Http.HttpMethod without custom TypeConverter for [Allowed<T>] and [Forbidden<T>].
v4.0.1
- Introduction of [InRange<TValue>] valiation attribute.
v4.0.0
- Validate public fields.
- Support primitives of the same type on [ValueOf<TValue>] attributes.
- Support requiredness via the required modifier.
- Introduction of [InPast] valiation attribute.
- Introduction of [InFuture] valiation attribute.
- Introduction of [NotInPast] valiation attribute.
- Introduction of [NotInFuture] valiation attribute.
- Introduction of [Items<TValidator>] to define a validator on the items of a collection.
- Introduction of [SkipValidation] to explictly skip validation of types and properties.
- Introduction of the [Validates(type)] attribute to decorate [Validation] attributes.
- Qowaiv.Validation.DataAnnotations.ValidationMessage.None returns null. (BREAKING)
- Refactor annotations resolving.
- Dropped AnnotatedModel. (BREAKING)
- Dropped AnnotatedProperty. (BREAKING)
- Dropped AnnotatedValidator. (BREAKING)
- Drop support on ValidationAttributes defined on types. (BREAKING)
- Update to Qowaiv v7.4.3.
v3.0.0
- Introduction of AllowedAttribute<T> as alternative to AllowedValuesAttribute.
- Introduction of DefinedOnlyAttribute<T> as alternative to DefinedEnumValuesOnlyAttribute.
- Introduction of ForbiddenAttribute<T> as alternative to ForbiddenValuesAttribute.
- Introduction of UniqueAttribute<T> as alternative to DistinctValuesAttribute.
- Marked AllowedValuesAttribute as obsolete.
- Marked DefinedEnumValuesOnlyAttribute as obsolete.
- Marked DistinctValuesAttribute as obsolete.
- Marked ForbiddenValuesAttribute as obsolete.
- Add .NET 9.0 target.
- Drop .NET 5.0, NET6.0, NET7.0 targets. (BREAKING)
- Drop binary serialization on exceptions. (BREAKING)
v2.0.0.
- Drop support .NET 5.0 and .NET 7.0. (breaking)
- Update to Qowaiv v7.0.0. (breaking)
- Introduction of [IsFinite] validation attribute.
- Introduction of [Length.AtLeast], [Length.AtMost], [Length.InRange].
- Introduction of [Collection.AtLeast], [Collection.AtMost], [Collection.InRange].
- Introduction of [Size.AtLeast], [Size.AtMost], [Size.InRange].
v1.4.0
- Introduced [MultipleOf] validation attribute. #69
- Marked [NestedModel] attribute as obsolete. #70
v1.3.0
- Support .NET 7.0. #62
v1.0.1
- Inaccessible properties do not crash but validate as invalid #58
- Indexed properties are ignored
v1.0.0
- Properties are considered validatable objects without [NestedModel] attribute #55
- Removed unused properties from NestedModel
v0.2.4
- Roll back of change #53
v0.2.3
- All models are considered to be nested. #52
- Fix crash on validation models with properties with generic types. #53
v0.2.2
- Mandatory attribute supports Dutch messages. #51
v0.2.1
- Nullable anotations. #48
v0.2.0
- Updated Qowaiv dependency.
v0.1.1
- Decorate pure methods with attribute (#38)
v0.1.0
- Qowaiv.Validation.Abstractions dependency
v0.0.4
- Fix double dots in paths for nested properties.