Friday, 3 March 2017

Validating User Input in Xamarin.Forms

Any mobile app that accepts user input should ensure that the input is valid. This could involve, for example, checking that input contains only characters in a particular range, or is of a certain length. Without validation, a user can supply data that can cause the app to fail.

In the context of MVVM, user input can be synchronously validated client-side in view model objects or in model objects. However, validating data in view models often means duplicating model properties. Instead, view models can delegate validation to the model objects they contain, with validation then being performed on the model objects. Validation rules can be specified on the model properties by using data annotations that derive from the ValidationAttribute class.

I’ve created a validation sample implements validation using this approach, which can be found on GitHub. The following diagram shows a high-level overview of the classes involved in validation:

Validation classes

To participate in validation, model classes must derive from the ValidatableBase class, which provides an error container whose contents are updated whenever a model class property value changes. The Validator and ValidatableBase classes both implement INotifyPropertyChanged in order to provide property change notification.

The SetProperty method in the ValidatableBase class performs validation when a model property is set to a new value. The validation rules come from data annotation attributes that derive from the ValidationAttribute class. The attributes are taken from the declaration of the model property being validated.

Users are notified of validation errors by highlighting the controls that contain the invalid data with red borders, and by displaying error messages that inform the user why the data is invalid, as shown in the following screenshot:

Validation errors

Over the coming weeks I’m going to explore this validation approach in a series of blog posts:

  1. Specifying validation rules.
  2. Triggering validation.
  3. Displaying validation errors.

In the meantime, the code can be downloaded from GitHub.

3 comments:

  1. Interesting approach but there is a detail that annoys me and it's that your model extends ViewModelBase. I dont’t see why it is required and I don't think it is a good practice either.

    ReplyDelete
    Replies
    1. Thanks for the feedback. It's a fair comment. Really, ViewModelBase isn't the best name for that class. In a full app I wouldn't expect ValidatableBase to extend ViewModelBase. Instead, I'd have a class that implements INPC (let's call it BindableBase for now), and ViewModelBase would extend BindableBase, and ValidatableBase would extend BindableBase. I'll do an update to make this cleaner.

      Delete
  2. I am amazed this is not part of the framework. User input validation is such a fundamental thing. In the meantime I propose they rebrand to 'Xamarin Un-validated Forms'

    ReplyDelete