You can now use an async
validation rule to execute field validation logic on a server. Implement the function validationCallback
to return a Promise (or the jQuery equivalent).
Here is an example:
$('#textBox').dxTextBox({ ... })
.dxValidator({
validationRules: [{
type: 'async',
message: 'Invalid value',
validationCallback: ({value}) =>
new Promise((resolve, reject) => {
fetch('https://mydomain.com/validationService', {
method: 'POST',
body: JSON.stringify({ data: value })
})
.then(res => {
if (!res.ok)
throw new Error(`HTTP error: ${res.status} ${res.statusText}`);
// Assuming the server returns JSON
return res.json();
})
.then(serverResult => {
// Server decided whether data is valid
if (serverResult.dataIsValid)
resolve();
else
reject(serverResult.errorMessage);
})
.catch(error => {
// There's been a technical error.
console.error('Server-side validation error', error);
// Decide what to tell the user.
reject('Cannot contact validation server');
});
});
}
}]
});
As you can see, validation succeeds if the Promise is resolved and fails if the Promise is rejected. However, there’s one more option. You can resolve the Promise with an object like this:
{
isValid: false,
message: 'Invalid value'
}
We support this scenario to allow you to return a server result directly, without any extra logic. In this case, even though the Promise is resolved, validation succeeds or fails depending on the isValid
property and the optional message
is shown to the user on failure. To illustrate this use case, here’s the shortest possible example:
validationCallback(params) {
return $.getJSON('https://mydomain.com/validationService',
{ data: params.value });
}
Note that without any processing, you may end up displaying technical errors to the end user as validation messages. We recommend more detailed algorithms which consider the edge cases, as shown in the first sample.
To keep validation efficient, any synchronous rules are always evaluated first, and asynchronous rules are only evaluated if all synchronous rules pass. Once asynchronous validation begins, all such rules are checked in parallel.
ASP.NET Core and ASP.NET MVC
We added support for the ASP.NET [Remote]
attribute to enable asynchronous validation on ASP.NET Core and ASP.NET MVC. You can apply this attribute to properties of your model, passing the names of a controller and a method to be called for validation:
[Remote("CheckEmailAddress", "Validation")]
public string Email { get; set; }
The attribute automatically generates client-side code for an ‘async’ validation rule, calling back to the controller running on the server. The controller method should check validity:
[HttpPost]
public IActionResult CheckEmailAddress(string email) {
if (!_userRepository.VerifyEmail(email)) {
return Json($"Email {email} is already registered.");
}
return Json(true);
}
This code uses return values as defined in Microsoft documentation for the .NET Core Remote attribute.
Alternatively you can return validity information in the JSON format described above, inluding the isValid
and message
fields. This allows you to create validation services in .NET Core which are compatible with clients written for other supported DevExtreme platforms.
Explicit Validation
If you call validate()
on a Validator or a ValidationGroup and there are asynchronous rules to be checked, you need to use the Promise interface provided by the property ValidationResult.complete to handle the results.
const result = validator.validate(); // OR validationGroup.validate();
result.complete.then(res => {
// res.status is 'valid' if all rules passed
// res.status is 'invalid' if any rules failed
if (res.status === 'invalid') {
// res.brokenRules contains an array of rules
// that failed validation
}
});
Limitations
At this time, asynchronous rules are not supported by the Data Grid and Tree List widgets when you use the Row, Batch or Cell editing modes. We will add this functionality in a future update.
Demo and Documentation
Here is the documentation for the ‘async’ rule..
The Validation Overview Demo includes samples of the ‘async’ rule for all supported platforms.