DataModel Validations
This document describes the set of validations supported by the Data Service for data model fields, how they are defined and enforced at runtime.
The validations exist in two layers:
- Definition layer (contract): serializable DTOs used in API contracts and persisted metadata, under
ASOL.DataService.Contracts.DataModelFieldValidations(and corresponding Primitives project). - Runtime layer (domain): executable validators under
ASOL.DataService.Domain.DataModelFieldValidationsthat perform the actual checks viaIsValid(object? value).
The conversion between the two is handled by DataModelFieldValidationHelper which:
- Verifies that a given validation is supported for the field’s
DataModelFieldTypeviaSupportedDataModelFieldTypesAttribute. - Maps each definition to its runtime counterpart (and vice versa) and copies parameters.
Validators
Below is the complete list of validators, their parameters, behavior, and notes. The examples show the definition-layer JSON as it appears in API requests/responses (see Swagger for the exact discriminator and property names).
Required
- Parameters
AllowEmptyStrings(bool)
- Behavior
- Valid when:
- The value is not
null. - For strings:
AllowEmptyStrings == trueallows any string including"";AllowEmptyStrings == falserequires a non-empty string. - For non-strings: any non-
nullvalue passes.
- The value is not
- Invalid when:
- The value is
null. - The value is a string that is empty (
"") andAllowEmptyStrings == false.
- The value is
- Throws when: never (this validator does not throw).
- Valid when:
- Runtime:
RequiredDataModelFieldValidation - Supported Field Types:
Text,MultilineText,TwoOptions,WholeNumber,DecimalNumber,UniqueIdentifier,UtcDateTime,LookupEntity,NestedEntity,Date,FileReference,CurrencyNumber,SingleSelectOptionSet,MultiSelectOptionSet - Example (definition):
{
"validation": "Required",
"allowEmptyStrings": false
}
MinValue
- Parameters
Minimum(IComparable: number, date/time, etc.)MinimumIsExclusive(bool) – iftrue, the value must be strictly greater thanMinimum.
- Behavior
- Valid when:
- The value is
null(not evaluated unless combined withRequired). - The value is comparable and the comparison satisfies:
- If
MinimumIsExclusive == false:value >= Minimum. - If
MinimumIsExclusive == true:value > Minimum.
- If
- The value is
- Invalid when:
- The value is comparable and the comparison fails the rule above.
- Throws when:
- The runtime value is not
IComparable.
- The runtime value is not
- Valid when:
- Runtime:
MinValueDataModelFieldValidation - Supported Field Types:
WholeNumber,DecimalNumber,UtcDateTime,Date - Special input support:
- For numeric fields, the runtime validator also accepts a string in the format
"<number>|<code>"(aka numberWithCode), for example"123.45|USD". In this case only the numeric part is used for comparison and the code segment is ignored.
- For numeric fields, the runtime validator also accepts a string in the format
- Example:
{
"validation": "MinValue",
"minimum": 0,
"minimumIsExclusive": false
}
MaxValue
- Parameters
Maximum(IComparable)MaximumIsExclusive(bool) – iftrue, the value must be strictly less thanMaximum.
- Behavior
- Valid when:
- The value is
null(not evaluated unless combined withRequired). - The value is comparable and the comparison satisfies:
- If
MaximumIsExclusive == false:value <= Maximum. - If
MaximumIsExclusive == true:value < Maximum.
- If
- The value is
- Invalid when:
- The value is comparable and the comparison fails the rule above.
- Throws when:
- The runtime value is not
IComparable.
- The runtime value is not
- Valid when:
- Runtime:
MaxValueDataModelFieldValidation - Supported Field Types:
WholeNumber,DecimalNumber,UtcDateTime,Date - Special input support:
- For numeric fields, the runtime validator also accepts a string in the format
"<number>|<code>"(aka numberWithCode), for example"123.45|USD". In this case only the numeric part is used for comparison and the code segment is ignored.
- For numeric fields, the runtime validator also accepts a string in the format
- Example:
{
"validation": "MaxValue",
"maximum": 100,
"maximumIsExclusive": true
}
Range
- Parameters
Minimum(IComparable)MinimumIsExclusive(bool)Maximum(IComparable)MaximumIsExclusive(bool)
- Behavior
- Valid when:
- The value is
null(not evaluated unless combined withRequired). - The value is comparable and the comparison satisfies BOTH:
- Lower bound: if
MinimumIsExclusive == false:value >= Minimum; iftrue:value > Minimum. - Upper bound: if
MaximumIsExclusive == false:value <= Maximum; iftrue:value < Maximum.
- Lower bound: if
- The value is
- Invalid when:
- The value is comparable and any of the bound checks above fails.
- Throws when:
- The runtime value is not
IComparable.
- The runtime value is not
- Valid when:
- Runtime:
RangeDataModelFieldValidation - Supported Field Types:
WholeNumber,DecimalNumber,UtcDateTime,Date - Special input support:
- For numeric fields, the runtime validator also accepts a string in the format
"<number>|<code>"(aka numberWithCode), for example"123.45|USD". In this case only the numeric part is used for both lower and upper bound comparisons and the code segment is ignored.
- For numeric fields, the runtime validator also accepts a string in the format
- Example:
{
"validation": "Range",
"minimum": 1,
"minimumIsExclusive": false,
"maximum": 10,
"maximumIsExclusive": true
}
StringLength
- Parameters
Length(uint)
- Behavior
- Valid when:
- The value is
null(not evaluated unless combined withRequired). - The value is a string and
string.Length == Length.
- The value is
- Invalid when:
- The value is a string and
string.Length != Length.
- The value is a string and
- Throws when:
- The value is not a string.
- Valid when:
- Runtime:
StringLengthDataModelFieldValidation - Supported Field Types:
Text,MultilineText - Example:
{
"validation": "StringLength",
"length": 36
}
StringMinLength
- Parameters
MinLength(uint)
- Behavior
- Valid when:
- The value is
null(not evaluated unless combined withRequired). - The value is a string and
string.Length >= MinLength.
- The value is
- Invalid when:
- The value is a string and
string.Length < MinLength.
- The value is a string and
- Throws when:
- The value is not a string.
- Valid when:
- Runtime:
StringMinLengthDataModelFieldValidation - Supported Field Types:
Text,MultilineText - Example:
{
"validation": "StringMinLength",
"minLength": 1
}
StringMaxLength
- Parameters
MaxLength(uint)
- Behavior
- Valid when:
- The value is
null(not evaluated unless combined withRequired). - The value is a string and
string.Length <= MaxLength.
- The value is
- Invalid when:
- The value is a string and
string.Length > MaxLength.
- The value is a string and
- Throws when:
- The value is not a string.
- Valid when:
- Runtime:
StringMaxLengthDataModelFieldValidation - Supported Field Types:
Text,MultilineText - Example:
{
"validation": "StringMaxLength",
"maxLength": 255
}
StringRangeLength
- Parameters
MinLength(uint)MaxLength(uint)
- Behavior
- Valid when:
- The value is
null(not evaluated unless combined withRequired). - The value is a string and
MinLength <= string.Length <= MaxLength(inclusive).
- The value is
- Invalid when:
- The value is a string and its length falls outside the inclusive range
[MinLength, MaxLength].
- The value is a string and its length falls outside the inclusive range
- Throws when:
- The value is not a string.
- Valid when:
- Runtime:
StringRangeLengthDataModelFieldValidation - Supported Field Types:
Text,MultilineText - Example:
{
"validation": "StringRangeLength",
"minLength": 2,
"maxLength": 5
}
Regex
- Parameters
Pattern(string, required)
- Behavior
- Valid when:
- The value is
null(not evaluated unless combined withRequired). - The value is a string and
Regex.IsMatch(value, Pattern)returnstrue.
- The value is
- Invalid when:
- The value is a string and it does not match
Pattern.
- The value is a string and it does not match
- Throws when:
- The value is not a string.
Patternisnullor empty.
- Valid when:
- Runtime:
RegexDataModelFieldValidation - Supported Field Types:
Text - Example:
{
"validation": "Regex",
"pattern": "^[A-Z]{3}-[0-9]{4}$"
}
DecimalPrecision
- Parameters
MaxPrecision(uint)
- Behavior
- Valid when:
- The value is
null(not evaluated unless combined withRequired). - The decimal scale (number of digits to the right of the decimal point) satisfies
scale <= MaxPrecision.
- The value is
- Invalid when:
- The decimal scale is greater than
MaxPrecision.
- The decimal scale is greater than
- Throws when:
- The value is not one of the supported numeric types.
- Valid when:
- Runtime:
DecimalPrecisionValidation - Supported Field Types:
DecimalNumber - Special input support:
- Additionally accepts a string in the format
"<number>|<code>"(aka numberWithCode), such as"1.23|USD". Only the numeric part is used to determine the scale (precision) and the code segment is ignored.
- Additionally accepts a string in the format
- Example:
{
"validation": "DecimalPrecision",
"maxPrecision": 2
}
Full example - data model with validations
{
"id": "60490ed4-533d-4a26-abd1-ca26ac457ecb",
"code": "MyModel01",
"name": "MyModel01",
"description": "MyModel01",
"notes": null,
"isAggregateRoot": true,
"fields": [
{
"name": "MyDecimalField0101",
"label": "MyDecimalField0101",
"description": "MyDecimalField0101",
"isPublishedForLookup": true,
"isCollection": false,
"isLocalized": false,
"isNullable": true,
"fieldType": "DecimalNumber",
"referencedEntityTypeIds": null,
"expression": null,
"fieldValidations": [
{
"validation": "MaxValue",
"maximum": 5
},
{
"validation": "DecimalPrecision",
"MaxPrecision": 2
}
]
},
{
"name": "MyStringField0102",
"label": "MyStringField0102",
"description": "MyStringField0102",
"isPublishedForLookup": true,
"isCollection": false,
"isLocalized": false,
"isNullable": true,
"fieldType": "Text",
"referencedEntityTypeIds": null,
"expression": null,
"fieldValidations": [
{
"validation": "StringRangeLength",
"minLength": 1,
"maxLength": 10
}
]
}
]
}