Validation
LightSpeed provides a rich, extensible object-level validation framework. An entity may be validated by calling the Entity.Validate method or querying the Entity.IsValid property. Validation errors are exposed at the entity-level through the bindable Entity.Errors collection. Custom validation may be performed by overriding the Entity.OnValidate method. Objects are always validated before they are saved to the database and a ValidationException will be raised if an attempt is made to save an invalid object.
Specifying Validation Criteria
To specify validation criteria for a property, select the property, go to the Properties window and enter the required validations.
The following validation options are available:
Validation | Description |
Validate Email | Ensures that the property contains a valid email address. In LightSpeed 5, this now supports emails with + and ‘ characters. |
Validate Format | For strings, ensures that the string conforms to the supplied regular expression |
Validate Length | For strings, validates the string length. Write <= n if the string must be no longer than n characters, >= n if the string must be at least n characters, and n ‑ m if the string must be between n and m characters. |
Validate Presence | Ensures that a value has been provided for the property. For numeric types, this means the value is non‑zero; for strings, it means the value is not null or the empty string. |
Validate Unique | Ensures that the property value is unique – ideal for email addresses, user names, etc. See Validation Considerations below. |
Validate URI | Ensures that the property contains a valid URI |
Validate Value | For numeric values, validates the property value. You can specify a range using the format min ‑ max, or a comparison using the =, !=, <, >, <= and >= operators, which have the same meanings as in C# (e.g. <= n to ensure that the value is less than or equal to n). |
Advanced Validation Options
If you need more fine control over validation than you can enter in the Properties window, you can use the LightSpeed Model Explorer to manage individual validation attributes. LightSpeed Model Explorer provides the following additional capabilities:
· Additional options such as the Allow Empty String option on PresenceValidation or the URI Kind or Is Required options on URI Validation.
· Custom error messages (select the validation and edit its Custom Error in the Properties window).
· Simplified editing user interface for Length and Range validations (separate entries in Properties window for maximum and minimum).
· Simplified editing for Comparison validations (drop-down list of operators).
· Support for custom validations. (Enter the validation attribute as you would like it emitted in the model code, excluding the surrounding brackets. For example, MyValidation(123). Note that, depending on the contents of the attribute declaration, this may make your model language-specific.)
To open the LightSpeed Model Explorer, choose View > Other Windows > LightSpeed Model. Then expand the tree view to show the property whose validation you want to customise, and open its Validations folder.
You can then modify validations through the Properties grid, and add them by right-clicking the property and choosing Add New validation_type Validation. In particular, to add a custom validation, choose Add New Custom Validation.
Note that some validation options in the Properties window may map to different underlying validation objects in the tree view. For example, a Validate Value expression may be implemented as a Range Validation or a Comparison Validation.
Automatic Validations
LightSpeed infers several validations automatically based on the underlying model.
· Association presence validation – ensures that any required associations are present. LightSpeed infers this based on whether the association foreign key field is nullable.
· DateTime range validation – ensures that any DateTime fields fall within a range acceptable for the database at hand.
These validations are built‑in and therefore result in built‑in messages. To override the message, you must apply a declarative validation in code (see below). Use the ValidateAttribute with a rule type of PresenceAssociationValidationRule or ProviderDateRangeValidationRule as appropriate, and specify your custom message on the ValidateAttribute.
Declarative Validation in Code
For hand‑coded entities or fields, you can specify validation by applying attributes to the field. (Remember LightSpeed attributes go on fields, not properties.)
Simple declarative validation |
[ValidateLength(0, 50)] |
The following attributes are available:
Attribute | Description |
ValidateAttribute | Used to specify a custom validation rule |
ValidateComparisonAttribute | Compares the target field to another value, e.g. less than 100 |
ValidateEmailAddressAttribute | Ensures that the property contains a valid email address |
ValidateFormatAttribute | For strings, ensures that the field conforms to the supplied regular expression |
ValidateLengthAttribute | For strings, ensures that the string length falls between the specified bounds |
ValidatePresenceAttribute | Ensures that a value has been provided for the property. For numeric types, this means the value is non‑zero; for strings, it means the value is not null or the empty string. |
ValidateRangeAttribute | For numeric values, validates that the value is within the specified range |
ValidateUniqueAttribute | Ensures that the property value is unique – ideal for email addresses, user names, etc. See Validation Considerations below. |
ValidateUriAttribute | Ensures that the property contains a valid URI |
Note that the designer merges some of these attributes (for example, the Validate Value option can map to either ValidateComparisonAttribute or ValidateRangeAttribute depending on the particular validation).
Overriding OnValidate
To perform more complicated validation, such as whole entity validation logic, override the Entity.OnValidate method. Report errors by adding them to the Errors collection.
Overriding OnValidate |
protected override void OnValidate() |
Validation Considerations
When using the Validate Unique validation (or the ValidateUniqueAttribute), you should be aware that:
· It incurs a COUNT(*) query against the database each time the validation runs. The designer will create a unique constraint on the column which should make this fast, but you should still be aware that it can cause a lot of queries during, for example, a bulk import.
· The check is performed against the database, not against other in‑memory entities. For example, if you create two new entities with the same value, and save them in the same unit of work, you can bypass the uniqueness validation. Again, a unique constraint at the database level will catch this, but it will result in a database exception rather than a validation exception.
· In LightSpeed 5, unique validation is scoped to the level which declares the field, not the level of the entity which is being validated at that time.
Localising Validation Messages
LightSpeed validation messages are intended to be human-readable. If you need to display messages in a language other than English, or just to replace the messages with your own messages, you can do so by creating a satellite resource DLL and/or a display naming strategy. For more information, see Localization in the Building Applications with LightSpeed chapter.
Basic Operations
The core operations of LightSpeed are the familiar CRUD (Create, Read, Update, Delete) database operations. The CRUD model lies behind the majority of database‑backed applications and Web sites. This chapter shows you how to implement CRUD using LightSpeed.