Skip to main content
Unlisted page
This page is unlisted. Search engines will not index it, and only users having a direct link can access it.

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.DataModelFieldValidations that perform the actual checks via IsValid(object? value).

The conversion between the two is handled by DataModelFieldValidationHelper which:

  • Verifies that a given validation is supported for the field’s DataModelFieldType via SupportedDataModelFieldTypesAttribute.
  • 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 == true allows any string including ""; AllowEmptyStrings == false requires a non-empty string.
      • For non-strings: any non-null value passes.
    • Invalid when:
      • The value is null.
      • The value is a string that is empty ("") and AllowEmptyStrings == false.
    • Throws when: never (this validator does not throw).
  • 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) – if true, the value must be strictly greater than Minimum.
  • Behavior
    • Valid when:
      • The value is null (not evaluated unless combined with Required).
      • The value is comparable and the comparison satisfies:
        • If MinimumIsExclusive == false: value >= Minimum.
        • If MinimumIsExclusive == true: value > Minimum.
    • Invalid when:
      • The value is comparable and the comparison fails the rule above.
    • Throws when:
      • The runtime value is not IComparable.
  • 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.
  • Example:
    {
    "validation": "MinValue",
    "minimum": 0,
    "minimumIsExclusive": false
    }

MaxValue

  • Parameters
    • Maximum (IComparable)
    • MaximumIsExclusive (bool) – if true, the value must be strictly less than Maximum.
  • Behavior
    • Valid when:
      • The value is null (not evaluated unless combined with Required).
      • The value is comparable and the comparison satisfies:
        • If MaximumIsExclusive == false: value <= Maximum.
        • If MaximumIsExclusive == true: value < Maximum.
    • Invalid when:
      • The value is comparable and the comparison fails the rule above.
    • Throws when:
      • The runtime value is not IComparable.
  • 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.
  • 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 with Required).
      • The value is comparable and the comparison satisfies BOTH:
        • Lower bound: if MinimumIsExclusive == false: value >= Minimum; if true: value > Minimum.
        • Upper bound: if MaximumIsExclusive == false: value <= Maximum; if true: value < Maximum.
    • Invalid when:
      • The value is comparable and any of the bound checks above fails.
    • Throws when:
      • The runtime value is not IComparable.
  • 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.
  • 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 with Required).
      • The value is a string and string.Length == Length.
    • Invalid when:
      • The value is a string and string.Length != Length.
    • Throws when:
      • The value is not a string.
  • 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 with Required).
      • The value is a string and string.Length >= MinLength.
    • Invalid when:
      • The value is a string and string.Length < MinLength.
    • Throws when:
      • The value is not a string.
  • 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 with Required).
      • The value is a string and string.Length <= MaxLength.
    • Invalid when:
      • The value is a string and string.Length > MaxLength.
    • Throws when:
      • The value is not a string.
  • 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 with Required).
      • The value is a string and MinLength <= string.Length <= MaxLength (inclusive).
    • Invalid when:
      • The value is a string and its length falls outside the inclusive range [MinLength, MaxLength].
    • Throws when:
      • The value is not a string.
  • 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 with Required).
      • The value is a string and Regex.IsMatch(value, Pattern) returns true.
    • Invalid when:
      • The value is a string and it does not match Pattern.
    • Throws when:
      • The value is not a string.
      • Pattern is null or empty.
  • 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 with Required).
      • The decimal scale (number of digits to the right of the decimal point) satisfies scale <= MaxPrecision.
    • Invalid when:
      • The decimal scale is greater than MaxPrecision.
    • Throws when:
      • The value is not one of the supported numeric types.
  • 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.
  • 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
}
]
}
]
}