Skip to content

Latest commit

 

History

History
140 lines (117 loc) · 3.64 KB

File metadata and controls

140 lines (117 loc) · 3.64 KB

Qowaiv DataAnnotations based validation

Provides an data annotations based implementation of the Qowaiv.Validation.Abstractions.IValidator and data annotation attributes.

Annotated model validator

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

Validation messages

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;
var info = ValidationMessage.Info(message, args);
var warn = ValidationMessage.Warning(message, args);
var error = ValidationMessage.Error(message, args);

Validation attributes

Multiple [System.ComponentModel.DataAnnotations.Validation] attributes can be used to decorate models.

Mandatory

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

    [Mandatory()]
    public string SomeString { get; set; }
}

Any

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

Allowed values

The [AllowedValues] attribute allows to define a subset of allowed values. It supports type converters to get the allowed values based on a string value.

public class Model
{
    [Allowed<Country>("DE", "FR", "GB")]
    public Country CountryOfBirth { get; set; }
}

Forbidden values

The [ForbiddenValues] attribute allows to define a subset of forbidden values. It supports type converters to get the forbidden values based on a string value.

public class Model
{
    [Forbidden<Country>("US", "IR")]
    public Country CountryOfBirth { get; set; }
}

Defined enum values only

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

Is finite

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

Multiple of

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

Optional

The [Optional] attribute indicates explicitly that a field is optional.

public class Model
{
    [Optional]
    public string? Message { get; set; }
}

Unique values

The [Unique&lt;TValue&gt;] attribute validates that all items of the collection are distinct. If needed, a custom IEqualityComparer&lt;TValue&gt comparer can be defined.

public class Model
{
    [Unique<int>(typeof(CustomEqualityComparer))]
    public IEnumerable<int> Numbers { get; set; }
}