Wednesday, 8 March 2017

Validating User Input in Xamarin.Forms II

Previously I introduced a high-level overview of an approach to validating user input in Xamarin.Forms. This approach involves specifying validation rules on model objects, invoking validation when a model property values changes, and then displaying any error messages. In this blog post I’m going to explore how to specify validation rules on model objects.

Specifying Validation Rules

Validation rules are specified by adding data annotation attributes, that derive from the ValidationAttribute class, to properties in model classes that require validation.

The following code example shows the User class, where the properties are decorated with validation attributes:

public class User : ValidatableBase { string forename, surname; const string NAMESREGEXPATTERN = @"\A\p{L}+([\p{Zs}\-][\p{L}]+)*\z"; [Required(ErrorMessage = "This field is required.")] [RegularExpression(NAMESREGEXPATTERN, ErrorMessage = "This field contains invalid characters.")] [StringLength(10, MinimumLength = 2, ErrorMessage = "This field requires a minimum of 2 characters and a maximum of 10.")] public string Forename { get { return forename; } set { SetProperty(ref forename, value); } } [Required(ErrorMessage = "This field is required.")] [RegularExpression(NAMESREGEXPATTERN, ErrorMessage = "This field contains invalid characters.")] [StringLength(15, MinimumLength = 2, ErrorMessage = "This field requires a minimum of 2 characters and a maximum of 15.")] public string Surname { get { return surname; } set { SetProperty(ref surname, value); } } }

The Required attribute specifies that a validation failure occurs if the field is null, contains an empty string, or contains only white-space characters. The RegularExpression attribute specifies that a property must match the regular expression given by the NAMESREGEXPATTERN constant. This regular expression allows user input to consist of all unicode name characters as well as spaces and hyphens, as long as the spaces and hyphens don’t occur in sequences and are not leading or trailing characters. The StringLength attribute specifies the minimum and maximum length of characters that are allowed. Each attribute also sets an ErrorMessage property, which stores the error message to be displayed if validation fails.

It’s worth browsing the DataAnnotations namespace in order to discover all the different validation attributes. As well as the general attributes mentioned above, it contains specific attributes capable of validating email addresses, credit card numbers, and phone numbers. In addition, it also provides a CustomValidation attribute, which specifies an application-provided method to be invoked to validate the property whenever a value is assigned to it.

To participate in validation a model class must derive from the ValidatableBase class, so that model property values will be validated when they change. In my next blog post I’ll explore this topic further. In the meantime, the code can be downloaded from GitHub.

5 comments:

  1. This is very cool, it follows the patterns from other Windows API.
    Couple of comments:

    1. I usually don't like attributes. For flexibility and other reasons, I remember WPF has stuff like IDataErrorInfo, INotifyDataErrorInfo. Not sure, does your mechanism uses that?

    2. It's a very useful feature, I wish it was in the framework already, any plans to bring this into Xamarin Forms?




    ReplyDelete
    Replies
    1. Answers:

      1. I hear you about attributes - they aren't for everyone. However, I also have a second validation approach that's attribute free. I'll blog about it once I finish writing about the current approach. Neither approaches are based on IDataErrorInfo.
      2. No. This approach is using functionality that's already available in .NET.

      Delete
    2. About #2: it would be useful to have in the framework the classes and interfaces which give basic support for validation. It would still be up to the developer to decide how to actually display it and implement it.
      What would be wrong with having this right in the Xamarin Forms?

      Delete
    3. Nothing would be wrong with it - it'd be great to have some validation support in Forms. That'd require getting it onto the roadmap, which requires it being proposed by management, or by the community (with plenty of backing) on the Xamarin.Forms Evolution forum.

      Delete
    4. Wow, sounds like it's a long way (and some luck) to have it into XF :)
      Too bad, it's really an useful feature.

      Delete