Write validation: API
-
Validate documents by defining a JSON schema, associating it with a document collection, and registering it with the server.
-
The schema sets constraints such as required fields, data types, and value ranges, that enforce document compliance during writing.
-
Validation is automatically triggered when documents in the associated collection are saved directly or via operations such as patching or ETL tasks.
-
In this article:
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.
- Usage
- 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));
{
// Define the allowed properties and their types
"properties": {
// 'Id' is the RavenDB document ID (e.g., "users/1-A")
"Id": { "type": "string" },
// 'Name' is the user's name, must be a non-empty string
"Name": { "type": "string", "minLength": 1 },
// 'Email' is the user's email address, must match a basic email pattern
"Email": {
"type": "string",
"pattern": "^[\\w\\.-]+@[\\w\\.-]+\\.\\w+$"
}
},
// These properties must be present in every User document
"required": ["Id", "Name", "Email"],
// Allow additional properties beyond those defined here
"additionalProperties": true
}
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.