# Validation Rules

We added a new Validation property extender to provide a modern, centralized, and flexible validation system to Wisej.NET applications.

Once you drop the new *Validation* component on a container at design time, all the controls are extended with a new property *ValidationRules*. You can assign multiple validation rules to any control.

{% hint style="info" %}
You can use the Validation component also directly in code. Instead of setting the ValidationRules property in the designer, simply call `validation.SetValidationRules(control, rules);`
{% endhint %}

There are 7 built-in validation rules:

1. **Required**: Validates the presence of any value.
2. **Email**: Validates an email entry.
3. **Decimal**: Validates a decimal value.
4. **Integer**: Validates an integer value.
5. **Currency**: Validates a currency value.
6. **Telephone**: Validates a phone number using a validation mask.
7. **Regex**: Validates any value using a custom regular expression.

Each built-in rule has a set of custom properties in addition to the basic properties inherited from the abstract *ValidationRule* class.

When design mode, you can add and manage the validation rules using Visual Studio's collection editor; it will automatically load the built-in rules and any custom rule you may have added to your solution.

<div align="left"><figure><img src="https://553579532-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MF1D11gPs_az3xaKusw%2Fuploads%2Fxe7EXiH9j1gC9oxV0G7K%2Fimage.png?alt=media&#x26;token=7d925aeb-2777-4777-9343-14f08c2f24b5" alt=""><figcaption><p>Example of a CurrencyValidationRule</p></figcaption></figure></div>

Once you add validation rules to a control, the Validation component will automatically attach to the control's Validating and Validated events and invoke the rules in sequence. When a rule fails to validate, it will set the [*InvalidMessage* ](https://docs.wisej.com/api/wisej.web/editors/wisej.web.textboxbase#invalidmessage)property of the control being validated, and set the *e.Cancel* property of the event to *true*.

*👉 This is more or less what you do now in code when handling the Validating event. With the difference that now you can reuse the same validation rule for multiple controls in an easy way.*

<div align="center"><figure><img src="https://553579532-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MF1D11gPs_az3xaKusw%2Fuploads%2F75xahWbfBVzNJT6fEiiA%2FWisej.CustomValidationTest%20(4).gif?alt=media&#x26;token=c1a9afc6-71a6-44f5-916b-e1c7d1282fbd" alt=""><figcaption><p>Standard validation</p></figcaption></figure></div>

### Custom Validation Rules

Build your own custom validation rule classes by extending *Wisej.Web.ValidationRule*. You can add any property and perform any validation procedure required by the application.

Using validation rule classes allows you to implement complex business rules for the validation of user-entered data in a single, reusable, place.

Example of a custom rule to enforce a minimum-age value:

```csharp
// ValidationRule to enforce a minimum age.
public class AgeValidationRule : ValidationRule
{
    public bool MinimumAgeInYears {
        get;
        set;
    }
    
    public override bool OnValidating(Control control) {
    
        if (DateTime.TryParse(control.Text, out DateTime value)) {
            return value < value.AddYears(-this.MinimumAge);
        }
        
        return false;
    }
}
```

### Error Providers

Validation messages are typically displayed in an error tooltip by setting the [*InvalidMessage* ](https://docs.wisej.com/api/wisej.web/editors/wisej.web.textboxbase#invalidmessage)property of an editor control. A second way to show validation errors, is to use the [*ErrorProvider* ](https://docs.wisej.com/docs/controls/extenders/errorprovider)extender. However, an application would have to explicitly set the error message in code when processing the *Validating* event.

The *Validation* extender, and each Validation rule, expose the ErrorProvider property (accepting any implementation of the new IErrorProvider interface), allowing the validation system to display the error message **anywhere!**

* On the control itself, the default.
* Using the [ErrorProvider ](https://docs.wisej.com/docs/controls/extenders/errorprovider)extender.
* On a separate [Label ](https://docs.wisej.com/docs/controls/content/label)(which now implements the *IErrorProvider* interface). :information\_source: The Label is automatically show or hidden.
* On any custom implementation of the new *IErrorProvider* interface: i.e, a [MessageBox](https://docs.wisej.com/docs/controls/notifications/messagebox), a slide-in Panel, any logger, etc.

We have also added two new interfaces:

* **IValidation**. All controls Controls that support the *InvalidMessage* property and fire Validating and Validated now implement this interface. (*it's similar to the IReadOnly or ILabel interfaces that normalize common features.*)
* **IErrorProvider**. Exposes the same two public methods implemented by the existing [ErrorProvider ](https://docs.wisej.com/docs/controls/extenders/errorprovider)component. Allows an application to have full control of where an how to show error information related to data field validation. The *Label* control now implements *IErrorProvider*.

<div align="center"><figure><img src="https://553579532-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MF1D11gPs_az3xaKusw%2Fuploads%2F6iR09JZQB5yUc6OjIomx%2FWisej.CustomValidationTest%20(2).gif?alt=media&#x26;token=f8d270f4-bc16-4f11-8140-e739b79a3c73" alt=""><figcaption><p>Validation using the ErrorProvider component</p></figcaption></figure></div>

### Custom Error Providers

Now any class can implement the *IErrorProvider* interface and be connected to either the *Validation* component or to any (even multiple) *ValidationRule* implementation.

The Wisej.Web.Label control implements the IErrorProvider interface and it automatically shows or hides itself when an error message is set or cleard.

<div align="center"><figure><img src="https://553579532-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MF1D11gPs_az3xaKusw%2Fuploads%2Fjtwpoy8PgDoVoAEwVe4f%2FWisej.CustomValidationTest%20(3).gif?alt=media&#x26;token=90361312-723d-4368-bb03-bc1441d5dead" alt=""><figcaption><p>Validation with rules set to use a label as the ErrorProvider.</p></figcaption></figure></div>

The code below shows a simple custom *IErrorProvider* that collects the errors and displays them in a list, all at once, in a *MessageBox*.

```csharp
// Custom error provider
public class MyErrorProvider : IErrorProvider
{
    private Dictionary<Control, string> errors = new Dictionary<Control, string>();
    
    public void SetError(Control control, string error) {
        errors[control] = error;
    }
    
    public string GetError(Control control) {
        return errors.TryGet(control, out string message) ? message : null;
    }
    
    public string[] GetErrors() {
        return errors.Select(
            e => $"<li>{((ILabel)e.Key).LabelText}: {e.Value}</li>").ToArray();
    }
}

// In a page.
// errorProvider is assigned to validation.ErrorProvider.

private MyErrorProvider errorProvider = new MyErrorProvider();

private async void button_Click(object sender, EventArgs e)
{
    // ensure all children are validated.
    ValidateChildren();
    
    // display all the errors in a MessageBox.
    var errors = errorProvider.GetErrors();
    if (errors.Length > 0)
        await MessageBox.ShowAsync($"<ul>{String.Join("", errors)}</ul>");
}

```

<div align="center"><figure><img src="https://553579532-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MF1D11gPs_az3xaKusw%2Fuploads%2FzTcPMJGNNxpiz4in6f5m%2FWisej.CustomValidationTest%20(1).gif?alt=media&#x26;token=c8db892a-c157-4f77-882f-5c5a6b1ed60c" alt=""><figcaption><p>Custom IErrorProvider implementation</p></figcaption></figure></div>

### Formatting Option

Validation rules are invoked twice, on *Validating* and on *Validated* events. A validation rule implementation may alter the text of a control while it's being validated or after it has been successfully validated.

For example, the built-in *CurrencyValidationRule* exposes a boolean *Format* property. When set to true, the rule will format the value of the control, if successfully validated, to display the currency symbol and the correct number of decimals.

### Validation Extender Events

The Validation extender exposes the same *Validating* and *Validated* events that are available to any control. However, for the Validation extender these events are fired for the controls that have been associated to at least one validation rule.

Your handler code attached to the Validation extender will receive the array with all the validation rules associated with the control being validated. This feature allows an application to perform additional custom validation at the Validation extender level, for all the related controls.
