Skip to main content

Write validation: API

Creating a validation schema

To validate documents against a JSON schema:

1. Define your schema as a string.

Ensure that the schema sets all the constraints needed to validate your documents.

Example:

// Ensure that a `Name` property exists.
string schemaJson = "{\"required\":[\"Name\"]}";

Example:

// Ensure that a `Name` property has a maximum length of 7 characters.
string schemaJson = "{\"properties\":{\"Name\":{\"maxLength\":7}}}";

2. Create the schema configuration.

Create a SchemaValidationConfiguration object and use it to enable validation and associate your schema with a document collection.

E.g., to associate your schema with the Users collection:

// Create the configuration
var configuration = new SchemaValidationConfiguration
{
Disabled = false, // Enable validation for all collections
ValidatorsPerCollection = new Dictionary<string, SchemaDefinition>
{
{ "Users", new SchemaDefinition
{
Disabled = false, // Enable validation for the Users collection
Schema = schemaJson
}
}
}
};

3. Register the schema with the server.

Use ConfigureSchemaValidationOperation to register the schema configuration with the server.

E.g.,

// Register the schema configuration with the server
await store.Maintenance.SendAsync(new ConfigureSchemaValidationOperation(configuration));

Once a schema is enabled for a collection, collection documents are validated when they are saved directly, as well as when they are added or modified by operations such as patching or ETL tasks. (See a list of operations that trigger validation.)

4. Validate documents.

After registering the schema, any document saved to the associated collection will be validated against the schema constraints.

E.g., attempting to save a document that violates the maxLength constraint will result in a SchemaValidationException such as:

Raven.Client.Exceptions.SchemaValidation.SchemaValidationException: The length of the value 'TooLongValue' at 'Name' should not exceed 7, but its actual length is 12.

To handle such exceptions, you can use a try-catch block when saving documents:

using (var session = store.OpenSession())
{
var user = new User { Name = "TooLongValue" }; // Violates maxLength constraint
session.Store(user);
try
{
session.SaveChanges(); // This will throw SchemaValidationException
}
catch (SchemaValidationException ex)
{
// Catch and handle the exception if the validation fails.
}
}

Example

In this example we validate documents saved in the Users collection by constraints set by a JSON schema.

// The JSON schema as a string (without comments)
var schemaJson = @"{
""type"": ""object"",
""properties"": {
""Id"": { ""type"": ""string"" },
""Name"": { ""type"": ""string"", ""minLength"": 1 },
""Email"": { ""type"": ""string"", ""pattern"": ""^[\\w\\.-]+@[\\w\\.-]+\\.\\w+$"" }
},
""required"": [""Id"", ""Name"", ""Email""],
""additionalProperties"": true
}";

var configuration = new SchemaValidationConfiguration
{
Disabled = false,
ValidatorsPerCollection = new Dictionary<string, SchemaDefinition>
{
{ "Users", new SchemaDefinition
{
Disabled = false,
Schema = schemaJson
}
}
}
};

await store.Maintenance.SendAsync(new ConfigureSchemaValidationOperation(configuration));

Available constraints

Your validation schema can set the following constraints:

type

Enforces the data type (e.g., "string", "number", "object", "array", "boolean", "integer").

Example: Name must be a string

{
"properties": {
"Name": { "type": "string" }
}
}

required

Enforces properties that must be present in the object.

Example: name must be a string, age must be an integer, and both are required.

{
"properties": {
"name": { "type": "string" },
"age": { "type": "integer" }
},
"required": ["name", "age"]
}

const

Requires a property to have a specific value.

Example: role must always be admin.

{
"properties": {
"role": { "const": "admin" }
}
}

enum

Restricts a property to a set of allowed values.

Example: status must be active, inactive, or pending.

{
"properties": {
"status": { "enum": ["active", "inactive", "pending"] }
}
}

minLength

Minimum number of characters for a string.

Example: username must be at least 3 characters long.

{
"properties": {
"username": { "type": "string", "minLength": 3 }
}
}

maxLength

Maximum number of characters for a string.

Example: code must be no more than 7 characters long.

{
"properties": {
"code": { "type": "string", "maxLength": 7 }
}
}

pattern

String must match a regular expression.

Example: email must match a basic email pattern.

{
"properties": {
"email": { "type": "string", "pattern": "^[\\w.-]+@[\\w.-]+\\.\\w+$" }
}
}

minimum

Minimum value for a number.

Example: age must be at least 18.

{
"properties": {
"age": { "type": "integer", "minimum": 18 }
}
}

maximum

Maximum value for a number.

Example: score must be no more than 100.

{
"properties": {
"score": { "type": "number", "maximum": 100 }
}
}

minItems

Minimum number of items in an array.

Example: The tags array must have at least 2 items.

{
"properties": {
"tags": { "type": "array", "minItems": 2 }
}
}

maxItems

Maximum number of items in an array.

Example: The tags array must have no more than 5 items.

{
"properties": {
"tags": { "type": "array", "maxItems": 5 }
}
}

properties

Defines schemas for each property of an object.

Example: firstName and lastName must be strings.

{
"properties": {
"firstName": { "type": "string" },
"lastName": { "type": "string" }
}
}

patternProperties

Defines validation rules for object properties whose names match a specified regular expression (regex) pattern.

Example: All properties starting with "foo_" must be strings, and those starting with "bar_" must be integers.

{
"type": "object",
"patternProperties": {
"^foo_": { "type": "string" },
"^bar_": { "type": "integer" }
},
"additionalProperties": false
}

additionalProperties

Controls whether properties not defined in properties and patternProperties are allowed.

Example: Only id is allowed.

{
"properties": {
"id": { "type": "string" }
},
"additionalProperties": false
}

items

Defines the schema for items in an array.

Example: scores must be an array of integers.

{
"properties": {
"scores": {
"type": "array",
"items": { "type": "integer" }
}
}
}

dependencies

Specifies property dependencies.

Example: If credit_card is present, billing_address must also be present.

{
"properties": {
"credit_card": { "type": "string" },
"billing_address": { "type": "string" }
},
"dependencies": {
"credit_card": ["billing_address"]
}
}

null

Allows a type or a property to be set to null (if supported by the implementation).

Example: Setting null for variable types. The value can be either a string or null.

{
"type": ["string", "null"]
}

Example: Setting null for properties. The middleName property can be either a string or null.

{
"properties": {
"middleName": { "type": ["string", "null"] }
}
}

Syntax

ConfigureSchemaValidationOperation definition:

// The schema validation configuration to apply.
// If `configuration` is null, `ArgumentNullException` is generated.
public ConfigureSchemaValidationOperation(SchemaValidationConfiguration configuration)

SchemaValidationConfiguration class:

public sealed class SchemaValidationConfiguration
{
// Indicates whether schema validation is globally disabled for the database.
// When true, validation is disabled for all collections regardless of
// individual collection settings.
// When false, validation is enabled based on the per-collection settings.
public bool Disabled { get; set; }

// Mapping of collection names to their corresponding schema definitions.
// Each entry specifies the JSON schema to be used for validating documents
// in the given collection.
// The collection name comparison is case-insensitive.
public Dictionary<string, SchemaDefinition> ValidatorsPerCollection { get; set; }
}

SchemaDefinition class:

public class SchemaDefinition
{
// Indicates whether schema validation is disabled for this collection.
// When true, documents will not be validated against the specified schema.
public bool Disabled { get; set; }

// The JSON schema definition as a string.
// Validates collection documents according to the schema specification.
public string Schema { get; set; }
}

SchemaValidationException message:

// Initializes a new `SchemaValidationException` instance with an error message
// that explains the reason for the schema validation failure.
// Typically specifies the document part that didn't comply with the schema.
public SchemaValidationException(string message)

The content of the exception message will vary based on the specific validation error encountered. A missing required property, for example, would yield:

Raven.Client.Exceptions.SchemaValidation.SchemaValidationException: 
The required property 'Company' is missing.