DevExtreme - Asynchronous Validation (v19.2)

DevExtreme Team Blog
20 December 2019

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).

Asynchronous Validation

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.

Free DevExpress Products - Get Your Copy Today

The following free DevExpress product offers remain available. Should you have any questions about the free offers below, please submit a ticket via the DevExpress Support Center at your convenience. We'll be happy to follow-up.
No Comments

Please login or register to post comments.