title | layout | order |
---|---|---|
Validation |
doc |
3 |
Assisticant supports validation using INotifyDataErrorInfo
in WPF. Validation on other platforms is not currently supported.
To enable validation on your view model, implement the IValidation
interface. This interface has one property: Rules
. Use the Validator
class to produce validation rules. Add properties using the For
method, providing a lambda selecting the property. Finish it off with a call to Build
.
public class PersonViewModel : IValidation
{
public string Name { get; set; }
public IValidationRules Rules => Validator
.For(() => Name)
.NotNullOrWhitespace()
.Build();
}
Provide validation rules for multiple properties with additional calls to For
.
public class PersonViewModel : IValidation
{
public string FirstName { get; set; }
public string LastName { get; set; }
public IValidationRules Rules => Validator
.For(() => FirstName)
.NotNullOrWhitespace()
.For(() => LastName)
.NotNullOrWhitespace()
.Build();
}
To display validation errors in XAML, set the ValidatesOnNotifyDataErrors
binding property.
<TextBox Binding="Name, ValidatesOnNotifyDataErrors=True">
The input must contain at least one character.
public class PersonViewModel : IValidation
{
public string Name { get; set; }
public IValidationRules Rules => Validator
.For(() => Name)
.NotNullOrEmpty()
.Build();
}
The input must contain at least one non-whitespace character.
public class PersonViewModel : IValidation
{
public string Name { get; set; }
public IValidationRules Rules => Validator
.For(() => Name)
.NotNullOrWhitespace()
.Build();
}
The input may contain no more than the specified number of characters. Nulls are allowed.
public class PersonViewModel : IValidation
{
public string Name { get; set; }
public IValidationRules Rules => Validator
.For(() => Name)
.MaxLength(50)
.Build();
}
The input must match the specified regular expression. If the whole string needs to match, then use "^" and "$". Otherwise, only part of the string must match. Nulls are allowed.
public class PersonViewModel : IValidation
{
public string PhoneNumber { get; set; }
public IValidationRules Rules => Validator
.For(() => PhoneNumber)
.Matches(@"^[0-9\-\(\)]*$")
.Build();
}
To disallow nulls, combine the rule with NotNull
public class PersonViewModel : IValidation
{
public string PhoneNumber { get; set; }
public IValidationRules Rules => Validator
.For(() => PhoneNumber)
.NotNull()
.Matches(@"^[0-9\-\(\)]*$")
.Build();
}
The following rules can be applied to any numeric properties, including int
, double
, decimal
, etc. They can also be used for comparing strings lexicographically.
The input must be greater than the supplied value.
public class PersonViewModel : IValidation
{
public int Age { get; set; }
public IValidationRules Rules => Validator
.For(() => Age)
.GreaterThan(0)
.Build();
}
To specify a range, combine two rules.
public class PersonViewModel : IValidation
{
public int Age { get; set; }
public IValidationRules Rules => Validator
.For(() => Age)
.GreaterThan(0)
.LessThan(150)
.Build();
}
The input must be greater than or equal to the supplied value.
public class PersonViewModel : IValidation
{
public decimal Price { get; set; }
public IValidationRules Rules => Validator
.For(() => Price)
.GreaterThanOrEqualTo(10.0m)
.Build();
}
The input must be less than the supplied value.
public class PersonViewModel : IValidation
{
public double Speed { get; set; }
public IValidationRules Rules => Validator
.For(() => Speed)
.LessThan(299792458.0)
.Build();
}
The input must be less than or equal to the supplied value.
public class PersonViewModel : IValidation
{
public byte Code { get; set; }
public IValidationRules Rules => Validator
.For(() => Code)
.LessThanOrEqualTo((byte)0x7f)
.Build();
}
The rules listed above will produce a validation message based on the property name and provided value. You can provide a custom message if the property name is not human readable, if the provided message does not give enough information, or if you want to localize the message. Call the WithMessage
method.
public class PersonViewModel : IValidation
{
public byte Code { get; set; }
public IValidationRules Rules => Validator
.For(() => Code)
.LessThanOrEqualTo((byte)0x7f)
.WithMessage(() => "The high bit of the code must be zero.")
.Build();
}
The rules listed above validate against constant values. To validate against other values, or to provide your own validation logic, use the Where
method. Provide a lambda that takes the property value and returns true
if it is valid. You must provide a validation message.
public class PersonViewModel : IValidation
{
public DateTime Birth { get; set; }
public DateTime? Death { get; set; }
public IValidationRules Rules => Validator
.For(() => Birth)
.Where(v => v <= DateTime.Today)
.WithMessage(() => "Birth date not be in the future.")
.For(() => Death)
.Where(v => v == null || v > Birth)
.WithMessage(() => "Death date must be after birth date.")
.Build();
}