Validation happens on write
The engine checks LegalValues, LegalCharacters, RegularExpression, MinValue/MaxValue,
MinLength/MaxLength, UniqueValues and MinNoInstances/MaxNoInstances every time a node is
written. A write that breaks a rule fails, and its whole transaction is rolled back. Stored values are
not checked again. If you tighten a rule, the database still opens, but a node that breaks the new
rule cannot be saved until its value is fixed.
A refused value throws a ValueConstraintException. Its PropertyId names the property, and its
message is written for the person who typed the value, for example
PostCode "12" is not valid: Enter four digits.
TrimandCaseTransformchange the value first: white space is removed from both ends, then the case is changed (invariant culture). The rules check the changed value, and the changed value is stored. So withCaseTransform = ToLowerCase, a unique email is unique however it is typed. Queries are not transformed: a query for"Ole@Example.com"on a lower-cased property finds nothing.RegularExpressionmust match every value written, the empty value too. A pattern like^[a-z0-9-]+$therefore makes the value required. For an optional value, allow empty in the pattern:^([a-z0-9-]+)?$. Without^and$, the pattern may match anywhere in the value. SetRegularExpressionMessageto say what a valid value looks like; without it, the message shows the pattern.LegalCharacterslists the characters a value may contain. The empty value is always allowed.UniqueValueson a string ignores case unless you setCaseSensitive = true. By default, no node can have"OLE"when another has"Ole". Only the check ignores case: the value is stored, sorted and queried as written.LegalValueson a string is compared ordinally. The empty value is always allowed, so addMinLength = 1to require a value.LegalValueson an integer limits a plainintto the listed values. An enum property is not limited to its members: a[Flags]combination, or a member a newer version of your code adds, is accepted.MinNoInstances/MaxNoInstanceson[Node]count the nodes of the type and of every type that inherits from it, including nodes that are unpublished, hidden or marked as deleted. The check is on what the whole transaction leaves, so deleting a node and inserting its replacement passes at the limit. A transaction that adds nodes is refused above the maximum, and one that removes nodes below the minimum, with aNodeTypeConstraintException. So withMinNoInstances = 1you can always insert the first node, but never delete the last.