Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
This module is a server side rules validation engine that can provide you with a unified approach to object, struct and form validation. You can construct validation constraint rules and then tell the engine to validate them accordingly.
Lucee 5+
ColdFusion 2016+
ColdBox validation is based on a way to declaratively specify validation rules for properties or fields in an object or form. The constraints can exist inside of the target object or you can define object and form constraints in your ColdBox configuration file so you can reuse validation constraints or as we call them: shared constraints.
You can then use 2 simple validation methods and report on the results: validate(), validateOrFail()
The ColdBox ORM Module is a professional open source software backed by Ortus Solutions, Corp offering services like:
Custom Development
Professional Support & Mentoring
Training
Server Tuning
Security Hardening
Code Reviews
Because of His grace, this project exists. If you don't like this, then don't read it, it's not for you.
"Therefore being justified by faith, we have peace with God through our Lord Jesus Christ: By whom also we have access by faith into this grace wherein we stand, and rejoice in hope of the glory of God." Romans 5:5
In cbValidation 1.5 we introduced the validateOrFail()
function. This function works in similar manner to the validate()
method, but instead of giving you the results object, it throws an exception.
So your validation fails, where are the results? In the exception structure under the extendedInfo
key. We store the validation results as JSON in the extended info and then you can use them for display purposes:
After validation you can use the same results object and use it to display the validation errors in your client side:
If you want more control you can use the hasErrors()
and iterate over the errors to display:
You can even use the results object in your views to get specific field errors, messagesbox, etc.
The following are some common methods from the validation result object for dealing with errors:
getResultMetadata()
getFieldErrors( [field] )
getAllErrors( [field] )
getAllErrorsAsJSON( [field] )
getAllErrorsAsStruct( [field] )
getErrorCount( [field] )
hasErrors( [field] )
getErrors()
The API Docs in the module (once installed) will give you the latest information about these methods and arguments.
Incoming Target
Validation Fails
Result
Object
false
Returns the same object
Object
true
Throws ValidationException
Struct
false
Returns the structure with ONLY the fields that were validated from the constraints
Struct
true
Throws ValidationException
try{
validateOrFail( target );
service.save( target );
} catch( ValidationException e ){
return {
"error" : true,
"validationErrors" : deserializeJSON( e.extendedInfo )
};
}
// store the validation results in the request collection
prc.validationResults = validate( obj );
<-- Display all errors as a message box --->
#getInstance( "MessageBox@cbMessagebox" )
.renderMessage( type="error", messageArray=prc.validationResults.getAllErrors() )#
<cfif prc.validationResults.hasErrors()>
<ul>
<cfloop array="#prc.validationResults.getErrors()#" index="thisError">
<li>#thisError.getMessage()#</li>
</cfloop>
</ul>
</cfif>
You can also define your constraints on the fly right where you are doing your validation.
In this sample we validate the public request context rc
. This sample validates all fields in the rc
. If you need more control you can specify the fields
parameter (default all) or the includeFields
and excludeFields
parameters in your validate()
call.
// sample REST API create user
function create( event, rc, prc ){
var validationResult = validate(
target = rc,
constraints = {
username = { required = true },
email = { required = true, type = "email" },
password = { required = true }
}
)
if ( !validationResult.hasErrors() ) {
UserService.createUser(rc.username, rc.email, rc.password);
prc.response.setData( UserService.readUser(username=rc.username) );
} else {
prc.response
.setError( true )
.addMessage( validationResult.getAllErrors())
.setStatusCode( STATUS.BAD_REQUEST )
.setStatusText( "Validation error" );
}
}
If you are using i18n (Internationalization and Localization) in your ColdBox applications you can also localize your validation error messages from the ColdBox validators.
You will do this by our lovely conventions for you resource bundle keys:
We also setup lots of global {Key}
replacements for your messages and also several that the core constraint validators offer as well:
{rejectedValue}
- The rejected value
{field}
or property - The property or field that was validated
{validationType}
- The name of the constraint validator
{validationData}
- The value of the constraint definition, e.g size=5..10, then this value is 5..10
{targetName}
- The name of the user, shared constraint or form
{DiscreteValidator}
- operation, operationValue
{InListValidator}
- inList
{MaxValidator}
- max
{MinValidator}
- min
{RangeValidator}
- range, min, max
{RegexValidator}
- regex
{SameAsValidator}
, {SameAsNoCaseValidator}
- SameAs
{SizeValidator}
- size, min, max
{TypeValidator}
- type
You can optionally register shared constraints in your file under the validation
directive. This means you register them with a unique name of your choice and its value is a collection of constraints for properties in your objects or forms.
Later on you will reference the key name in your handlers or wherever in order to validate the object or form. Here is an example:
As you can see, our constraints definition describes the set of rules for a property on ANY target object or form.
You can then use the keys for those constraints in the validation calls:
The module will register several objects into WireBox using the @cbvalidation
namespace. The validation manager is registered as ValidationManager@cbvalidation
, which is the one you can inject and use anywhere you like.
By default if a constraint fails an error message will be set in the result objects for you in English. If you would like to have your own custom messages for specific constraints you can do so by following the constraint message convention:
Just add the name of the constraint you like and append to it the work Message and you are ready to roll:
{ObjectName}.{Field}.{ConstraintType}}=Message
{SharedConstraintName}.{Field}.{ConstraintType}=Message
GenericForm.{Field}.{ConstraintType}=Message
blank=The field {property} must contain a value.
email=The field {property} is not a valid email address.
unique=The field {property} is not a unique value.
size=The field {property} was not in the size range of {size}.
inlist=The field {property} was not in the list of possible values.
validator=There was a problem with {property}.
min=The minimum value {min} was not met for the field {property}.
max=The maximum value {max} was exceeded for the field {property}.
range=The range was not met for the field {property}.
matches=The field {property} does not match {regex}.
numeric=The field {property} is not a valid number.
// get reference
property name="validationManager" inject="ValidationManager@cbvalidation";
{constraintName}Message = "My Custom Message";
username = {
required="true",
requiredMessage="Please enter the username",
size="6-8",
sizeMessage="The username must be between 6 to 8 characters"
}
validation = {
sharedConstraints = {
sharedUser = {
fName = {required=true},
lname = {required=true},
age = {required=true, max=18 }
metadata = {required=false, type="json"}
},
loginForm = {
username = {required=true}, password = {required=true}
},
changePasswordForm = {
password = {required=true,min=6}, password2 = {required=true, sameAs="password", min=6}
}
}
}
validate( target, "sharedUser" );
validate( rc, "loginForm" );
validate( rc, "changePasswordForm" );
Here are the module settings you can place in your ColdBox.cfc
by using the validation
settings structure:
validation = {
// The third-party validation manager to use, by default it uses CBValidation.
manager = "class path",
// You can store global constraint rules here with unique names
sharedConstraints = {
name = {
field = { constraints here }
}
}
}
Key
Type
Required
Default
Description
manager
instantiation path or WireBox ID
false
cbValidation.models.ValidationManager
You can override the module manager with your own implementation. Just use an instantiation path or a valid WireBox object id.
sharedConstraints
struct
false
{}
This structure will hold all of your shared constraints for forms or/and objects.
Important: The module will register several objects into WireBox using the @cbvalidation
namespace. The validation manager is registered as ValidationManager@cbvalidation
We also have the ability to validate a target object or form with shared constraints from our configuration file. Just use the name of the key in the configuration form as the name of the constraints
argument.
// validate user object
prc.results = validateModel( target=user, constraints="sharedUser" );
// validate incoming form elements in the RC or request collection
prc.results = validateModel( target=rc, constraints="sharedUser" );
This will validate the object and rc
using the sharedUser
constraints.
Just drop into your modules folder or use CommandBox to install
box install cbvalidation
The module will register several objects into WireBox using the @cbvalidation
namespace. The validation manager is registered as ValidationManager@cbvalidation
. It will also register several helper methods that can be used throughout the ColdBox application.
The module will also register two methods in your handlers/interceptors/layouts/views
validate()
validateOrFail()
getValidationManager()
/**
* Validate an object or structure according to the constraints rules.
* @target An object or structure to validate
* @fields The fields to validate on the target. By default, it validates on all fields
* @constraints A structure of constraint rules or the name of the shared constraint rules to use for validation
* @locale The i18n locale to use for validation messages
* @excludeFields The fields to exclude in the validation
*
* @return cbvalidation.model.result.IValidationResult
*/
function validate()
/**
* Validate an object or structure according to the constraints rules and throw an exception if the validation fails.
* The validation errors will be contained in the `extendedInfo` of the exception in JSON format
*
* @target An object or structure to validate
* @fields The fields to validate on the target. By default, it validates on all fields
* @constraints A structure of constraint rules or the name of the shared constraint rules to use for validation
* @locale The i18n locale to use for validation messages
* @excludeFields The fields to exclude from the validation
* @includeFields The fields to include in the validation
*
* @return The validated object or the structure fields that where validated
* @throws ValidationException
*/
function validateOrFail(){
return getValidationManager().validateOrFail( argumentCollection=arguments );
}
/**
* Retrieve the application's configured Validation Manager
*/
function getValidationManager()
Within any domain object you can define a public variable called constraints
that is a assigned an implicit structure of validation rules for any fields or properties in your object.
We can then create the validation rules for the properties it will apply to it:
That easy! You can just declare these validation rules and ColdBox will validate your properties according to the rules. In this case you can see that a password must be between 6 and 10 characters long, and it cannot be blank.
You can then use them implicitly
component persistent="true"{
// Object properties
property name="id" fieldtype="id" generator="native" setter="false";
property name="fname";
property name="lname";
property name="email";
property name="username";
property name="password";
property name="age";
// Validation
this.constraints = {
// Constraints go here
}
}
component persistent="true"{
...
// Validation
this.constraints = {
fname = { required = true },
lname = { required = true},
username = {required=true, size="6..10"},
password = {required=true, size="6..8"},
email = {required=true, type="email"},
age = {required=true, type="numeric", min=18}
};
}
validate( myUser );
You can define constraints in several locations:
When validating using validate(), validateOrFail()
you have to specify a target, but specifying a constraint in your call is optional.
When you call the validation methods with NO constraints
passed explicitly, then the validation module will following this lookup procedure:
Lookup your constraints in myTarget.constraints
struct in your target object or struct.
If you specify your constraint parameter as a string, the validator will lookup a shared constraint in your configuration file.
If you specify your constraint parameter as a struct, this struct will directly server as your set of constraints, so you can specify your constraints on the fly, or specify an alternative set of constraints in your model, e.g User.constraints
vs User.signInConstraints
If you would like to adapt your own validation engines to work with ANY ColdBox application you can do this by implementing the following interfaces:
Validation Manager : Implement the cbvalidation.models.IValidationManager
. Then use the class path in your configuration file so it uses your validation manager instead of ours.
Validation Results : Implement the cbvalidation.models.result.IValidationResult
, which makes it possible for any ColdBox application to use your validation results.
Validation Error : Implement the cbvalidation.models.result.IValidationError
, which makes it possible for any ColdBox application to use your validation error representations.
We also setup lots of global {Key}
replacements for your messages and also several that the core constraint validators offer as well. This is great for adding these customizations on your custom messages and also your i18n messages (Keep Reading):
{rejectedValue}
- The rejected value
{field or property}
- The property or field that was validated
{validationType}
- The name of the constraint validator
{validationData}
- The value of the constraint definition, e.g size=5..10, then this value is 5..10
{DiscreteValidator}
- operation, operationValue
{InListValidator}
- inList
{MaxValidator}
- max
{MinValidator}
- min
{RangeValidator}
- range, min, max
{RegexValidator}
- regex
{SameAsValidator}
, {SameAsNoCaseValidator}
- sameas
{SizeValidator}
- size, min, max
{TypeValidator}
- type
username = {
required="true",
requiredMessage="Please enter the {field}",
size="6-8",
sizeMessage="The username must be between {min} and {max} characters"
}
Most likely you will be validating your objects at the controller layer in your ColdBox event handlers. All event handlers,layouts, views and interceptors have some new methods thanks to our module mixins.
/**
* Validate an object or structure according to the constraints rules.
* @target An object or structure to validate
* @fields The fields to validate on the target. By default, it validates on all fields
* @constraints A structure of constraint rules or the name of the shared constraint rules to use for validation
* @locale The i18n locale to use for validation messages
* @excludeFields The fields to exclude in the validation
*
* @return cbvalidation.model.result.IValidationResult
*/
function validate()
/**
* Validate an object or structure according to the constraints rules and throw an exception if the validation fails.
* The validation errors will be contained in the `extendedInfo` of the exception in JSON format
*
* @target An object or structure to validate
* @fields The fields to validate on the target. By default, it validates on all fields
* @constraints A structure of constraint rules or the name of the shared constraint rules to use for validation
* @locale The i18n locale to use for validation messages
* @excludeFields The fields to exclude from the validation
* @includeFields The fields to include in the validation
*
* @return The validated object or the structure fields that where validated
* @throws ValidationException
*/
function validateOrFail(){
return getValidationManager().validateOrFail( argumentCollection=arguments );
}
/**
* Retrieve the application's configured Validation Manager
*/
function getValidationManager()
You pass in your target object or structure, an optional list of fields or properties to validate only (by default it does all of them), an an optional constraints argument which can be the shared name or an actual constraints structure a-la-carte. If no constraints are passed, then we will look for the constraints in the target object as a public property called constraints
. The validate()
method returns a cbvalidation.models.results.IValidationResult
type object, which you can then use for evaluating the validation.
function saveUser(event,rc,prc){
// create and populate a user object from an incoming form
var user = populateModel( entityNew("User") );
// validate model
prc.validationResults = validate( user );
if( prc.validationResults.hasErrors() ){
// show errors
}
else{
// save
}
}
The return of validate model is our results interface which has cool methods like:
interface{
/**
* Add errors into the result object
* @error.hint The validation error to add into the results object
*/
IValidationResult function addError(required IValidationError error);
/**
* Set the validation target object name
*/
IValidationResult function setTargetName(required string name);
/**
* Get the name of the target object that got validated
*/
string function getTargetName();
/**
* Get the locale
*/
string function getLocale();
/**
* has locale information
*/
boolean function hasLocale();
/**
* Set the validation locale
*/
IValidationResult function setLocale(required string locale);
/**
* Determine if the results had error or not
* @field.hint The field to count on (optional)
*/
boolean function hasErrors(string field);
/**
* Clear All errors
*/
IValidationResult function clearErrors();
/**
* Get how many errors you have
* @field.hint The field to count on (optional)
*/
numeric function getErrorCount(string field);
/**
* Get the Errors Array, which is an array of error messages (strings)
* @field.hint The field to use to filter the error messages on (optional)
*/
array function getAllErrors(string field);
/**
* Get an error object for a specific field that failed. Throws exception if the field does not exist
* @field.hint The field to return error objects on
*/
IValidationError[] function getFieldErrors(required string field);
/**
* Get a collection of metadata about the validation results
*/
struct function getResultMetadata();
/**
* Set a collection of metadata into the results object
*/
IValidationResult function setResultMetadata(required struct data);
}
Some of these methods return error objects which adhere to our Error Interface: cbvalidation.models.result.IValidationError
, which can quickly tell you what field had the exception, what was the rejected value and the validation message:
/**
* Set error metadata that can be used in i18n message replacements or in views
* @data.hint The name-value pairs of data to store in this error.
*/
IValidationError function setErrorMetadata(required any data);
/**
* Get the error metadata
*/
struct function getErrorMetadata();
/**
* Set the error message
* @message.hint The error message
*/
IValidationError function setMessage(required string message);
/**
* Set the field
* @message.hint The error message
*/
IValidationError function setField(required string field);
/**
* Set the rejected value
* @value.hint The rejected value
*/
IValidationError function setRejectedValue(required any value);
/**
* Set the validator type name that rejected
* @validationType.hint The name of the rejected validator
*/
IValidationError function setValidationType(required any validationType);
/**
* Get the error validation type
*/
string function getValidationType();
/**
* Set the validator data
* @data.hint The data of the validator
*/
IValidationError function setValidationData(required any data);
/**
* Get the error validation data
*/
string function getValidationData();
/**
* Get the error message
*/
string function getMessage();
/**
* Get the error field
*/
string function getField();
/**
* Get the rejected value
*/
any function getRejectedValue();
You can use multiple custom validators or pass in arbitrary data to custom validators by specifying the validator name as the key in the rules struct.
//sample custom validator constraints
this.constraints = {
myField = {
UniqueInDB = {
table= "table_name",
column = 'column_name'
}
}
};
This example will look for a UniqueInDBValidator
in WireBox and pass in { table = "table_name", column = "column_name" }
to the validate
method.
//sample validator
/**
* UniqueInDB validator. This checks and returns fals if value is already present in DB
*/
component singleton implements="cbvalidation.models.validators.IValidator" accessors="true" {
/**
* Constructor
*/
UniqueInDB function init(){
variables.Name = "UniqueInDBValidator";
return this;
}
/**
* validate
*/
boolean function validate(
required cbvalidation.models.result.IValidationResult validationResult,
required any target,
required string field,
any targetValue,
any validationData
){
//check validationdata
if ( !IsStruct(validationData ) ) {
throw(message="The validator data is invalid: #arguments.validationData#, it must be a struct with keys 'table' = 'tableName' and 'column' = 'columnName'");
}
//check validationdata
if ( !structKeyExists(validationData,"table") || !structKeyExists(validationData,"column") ) {
throw(message="The validator data is invalid: #serializeJSON(validationData)# it must be a struct with keys 'table' = 'tableName' and 'column' = 'columnName'");
}
var myParams = { table =validationData.table, column=validationData.column, columnvalue=targetValue };
var sql = "Select #validationData.column# from #validationData.table# where #validationData.column# = :columnvalue";
var myQuery = queryExecute(sql, myParams);
// This sample only validates NEW records, additional code is necessary for EDITING existing records
if (myQuery.recordcount == 0) {
return true
}
// error messages definieren
var args = {
message="The value #targetValue# is not unique in your database",
field=arguments.field,
validationType=getName(),
validationData=arguments.validationData
};
var error = validationResult.newError(argumentCollection=args).setErrorMetadata({table=validationData.table, column=validationData.column});
validationResult.addError( error );
return false;
}
/**
* getName
*/
string function getName(){
return variables.Name
}
}
Using these advanced techniques you can build reusable validators that accept the data they need in the validationData
struct. You can also include multiple custom validators just by specifying each of them as a key.
If you don't have any custom data to pass to a validator, just pass an empty struct ({}
)
WARNING: You can't do a normal wirebox mapping for YourOwnValidator
in your main application. A validator needs an IValidator
interface from the cbvalidation
module. When wirebox inspects the binder, the cbvalidation
module is not loaded yet, so it will error. This can be solved by defining your custom validators in an own module (depending on cbvalidation
) or by mapping your validator in the afterConfigurationLoad()
method of your binder, e.g in config/wirebox.cfc
You can build also your own validators by implementing our interface cbvalidaton.models.validators.IValidator
:
The arguments received are:
validationResults
: The validation result object
field
: The field or property in the object that is in validation
targetValue
: The value to test
Here is a sample validator:
WARNING: You can't do a normal wirebox mapping for YourOwnValidator
in your main application. A validator needs an IValidator
interface from the cbvalidation
module. When wirebox inspects the binder, the cbvalidation
module is not loaded yet, so it will error. This can be solved by defining your custom validators in an own module (depending on cbvalidation
) or by mapping your validator in the afterConfigurationLoad()
method of your binder, e.g in config/wirebox.cfc
/**
* Will check if an incoming value validates
* @validationResult.hint The result object of the validation
* @target.hint The target object to validate on
* @field.hint The field on the target object to validate on
* @targetValue.hint The target value to validate
*/
boolean function validate(required cbvalidation.models.result.IValidationResult validationResult, required any target, required string field, any targetValue, any validationData);
/**
* Get the name of the validator
*/
string function getName();
/**
********************************************************************************
Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp
www.coldbox.org | www.luismajano.com | www.ortussolutions.com
********************************************************************************
The ColdBox validator interface, all inspired by awesome Hyrule Validation Framework by Dan Vega
*/
component accessors="true" implements="cbvalidation.models.validators.IValidator" singleton{
property name="name";
MaxValidator function init(){
name = "Max";
return this;
}
/**
* Will check if an incoming value validates
* @validationResult.hint The result object of the validation
* @target.hint The target object to validate on
* @field.hint The field on the target object to validate on
* @targetValue.hint The target value to validate
* @validationData.hint The validation data the validator was created with
*/
boolean function validate(required cbvalidation.models.result.IValidationResult validationResult, required any target, required string field, any targetValue, string validationData){
// Simple Tests
if( !isNull(arguments.targetValue) AND arguments.targetValue <= arguments.validationData ){
return true;
}
var args = {message="The '#arguments.field#' value is not less than #arguments.validationData#",field=arguments.field,validationType=getName(),validationData=arguments.validationData};
var error = validationResult.newError(argumentCollection=args).setErrorMetadata({max=arguments.validationData});
validationResult.addError( error );
return false;
}
/**
* Get the name of the validator
*/
string function getName(){
return name;
}
}
The unique
constraint is part of the cborm module. So make sure that the cborm
module is installed first.
box install cborm
The constraints is mapped into WireBox as UniqueValidator@cborm
so you can use in your constraints like so:
{ fieldName : { validator: "UniqueValidator@cborm" } }
If you will be using the unique constraint, then the name of the property has to be EXACTLY the same case as the constraint name. To do this, use single or double quotes to declare the constraint name. Please see example below.
this.constraints = {
"username" = { required=true, validator: "UniqueValidator@cborm" },
"email" = { required=true, validator: "UniqueValidator@cborm" }
};
We also have the ability to validate a target object with custom a-la-carte constraints by passing the constraints inline as an struct of structs. This way you can store these constraint rules anywhere you like.
myConstraints = {
login = { required=true, size=6..10 },
password = { required=true, size=6..10 }
};
prc.results = validateModel( target=user, constraints=myConstraints );
This will validate the object using the inline constraints that you built.
Below are all the currently supported constraints. If you need more you can create your own Custom validators.
propertyName = {
// required field or not, includes null values
required : boolean [false],
// specific type constraint, one in the list.
type : (ssn,email,url,alpha,boolean,date,usdate,eurodate,numeric,GUID,UUID,integer,string,telephone,zipcode,ipaddress,creditcard,binary,component,query,struct,json,xml),
// size or length of the value which can be a (struct,string,array,query)
size : numeric or range, eg: 10 or 6..8
// range is a range of values the property value should exist in
range : eg: 1..10 or 5..-5
// regex validation
regex : valid no case regex
// same as another property
sameAs : propertyName
// same as but with no case
sameAsNoCase : propertyName
// value in list
inList : list
// value is unique in the database via the cborm module, it must be installed
unique : true
// discrete math modifiers
discrete : (gt,gte,lt,lte,eq,neq):value
// UDF to use for validation, must return boolean accept the incoming value and target object, validate(value,target):boolean
udf = variables.UDF or this.UDF or a closure.
// Validation method to use in the target object must return boolean accept the incoming value and target object
method : methodName
// Custom validator, must implement coldbox.system.validation.validators.IValidator
validator : path or wirebox id, example: 'mypath.MyValidator' or 'id:MyValidator'
// min value
min : value
// max value
max : value
}
Constraint
Type
Default
required
boolean
false
Whether the property must have a non-null value
type
string
string
Validates that the value is of a certain format type. Our included types are: ssn,email,url,alpha,boolean,date,usdate,eurodate,numeric,GUID,UUID,integer,string,telephone,zipcode,ipaddress,creditcard,binary,component,query,struct,json,xml
size
numeric or range
---
The size or length of the value which can be a struct, string, array, or query. The value can be a single numeric value or our cool ranges. Ex: size=4, size=6..8, size=-5..0
range
range
---
Range is a range of values the property value should exist in. Ex: range=1..10, range=6..8
regex
regular expression
---
The regular expression to try and match the value with for validation. This is a no case regex check.
sameAs
propertyName
---
Makes sure the value of the constraint is the same as the value of another property in the object. This is a case sensitive check.
sameAsNoCase
propertyName
---
Makes sure the value of the constraint is the same as the value of another property in the object with no case sensitivity.
inList
string list
---
A list of values that the property value must exist in
discrete
string
---
Do discrete math in the property value. The valid values are: eq,neq,lt,lte,gt,gte. Example: discrete="eq:4" or discrete="lte:10"
udf
UDF or closure
---
I can do my own custom validation by doing an inline closure (CF 10 or Railo only) or a pointer to a custom defined function. The function must return boolean and accepts two parameters: value and target.
method
method name
---
The name of a method to call in the target object for validation. The function must return boolean and accepts two parameters: value and target.
min
numeric
---
The value must be greater than or equal to this minimum value
max
numeric
---
The value must be less than or equal to this maximum value
validator
instantiation path or wirebox DSL
---
You can also build your own validators instead of our internal ones. This value will be the instantiation path to the validator or a wirebox id string. Example: validator="mymodel.validators.MyValidator", validator="id:MyValidator"
With the validator
constraint you can specify your own custom validator, but if you need your own parameters for your validator this is a bit limited. You can also specify YourOwnValidator
as constraint label where YourOwnValidator
is a wirebox id string. In this case you can specify your own parameters.
See Advanced Custom Validators for details.
WARNING: You can't do a normal wirebox mapping for YourOwnValidator
in your main application. A validator needs an IValidator
interface from the cbvalidation
module. When wirebox inspects the binder, the cbvalidation
module is not loaded yet, so it will error. This can be solved by defining your custom validators in an own module (depending on cbvalidation
) or by mapping your validator in the afterConfigurationLoad()
method of your binder, e.g in config/wirebox.cfc
You can also tell the validation manager to ONLY validate on certain fields and not all the fields declared in the validation constraints.
prc.results = validateModel( target=user, fields="login,password" );
This will only validate the login
and password
fields.