Data annotations in Windows Phone 8.1

This article describes about implementation and usage of the data annotations in Windows Phone 8.1.

Universal WINRT apps targeting Windows 8.1 and Phone 8.1 have lack of built in support for data annotations or field validations. Hence, created the below custom Validation base project to support the data annotations mechanism in Universal apps.
Created the PCL (Portable Class Library) project for implementation of custom validation base, so you can use the same assembly for cross platform apps as well.

The library comes with support for validating minimum and maximum numeric values, ranges of numeric values, string length, null objects, empty collections, empty or null strings and custom delegate method invocation.
If you want to write your own attribute validation, you just need to implement IValidationRule and then decorate your object.



In this sample, created a user model with Email and password properties. Now, validate the Email address is not blank and is in a valid format. Also validate the Password property.

public class User : ValidatableBase, INotifyPropertyChanged
{
     private string email = string.Empty;

    private string password = string.Empty;

    [ValidateObjectHasValue(FailureMessage = "E-Mail can not be left blank.", ValidationMessageType = typeof(ValidationErrorMessage))]
    [ValidateWithCustomHandler(DelegateName = "ValidateEmailFormat", ValidationMessageType = typeof(ValidationErrorMessage), FailureMessage = "Email address is not properly formatted.")]
    public string Email
    {
         get
        {
            return this.email;
        }

         set
         {
             this.email = value;
             this.OnPropertyChanged("Email");
        }
    }

    [ValidateStringIsGreaterThan(GreaterThanValue = 6, ValidateIfMemberValueIsValid = "Email",  FailureMessage = "Password must be greater than 6 characters.", ValidationMessageType = typeof(ValidationErrorMessage))]
    [ValidateStringIsLessThan(LessThanValue = 20, ValidateIfMemberValueIsValid = "Email", FailureMessage = "Password must be less than 20 characters.", ValidationMessageType = typeof(ValidationErrorMessage))]
     public string Password
    {
         get
        {
            return this.password;
        }

        set
         {
             this.password = value;
             this.OnPropertyChanged("Password");
        }
    }

    [ValidationCustomHandlerDelegate(DelegateName = "ValidateEmailFormat")]
    private IValidationMessage ValidateEmailIsFormatted(IValidationMessage failureMessage, PropertyInfo property)
    {
        string[] addressParts = this.Email.Split('@');

        if (addressParts.Length < 2)
        {
            return failureMessage;
        }

        string[] domainPiece = addressParts.LastOrDefault().Split('.');
        if (domainPiece.Length < 2)
        {
            return failureMessage;
        }

        return null;
    }

    public event PropertyChangedEventHandler PropertyChanged;

     protected virtual void OnPropertyChanged(string propertyName = "")
    {
        var handler = PropertyChanged;

         if (handler != null)
        {
             handler(this, new PropertyChangedEventArgs(propertyName));
         }
    }
}

From above, created the delegate methods and invoking per property

In view model, create a user model property for model data and create a property to hold the validation messages which will be bind as error messages in UI.
public Dictionary<string, ObservableCollection<IValidationMessage>> ValidationMessages
        {
             get
             {
                 return this.validationMessages;
             }

             private set
            {
                 this.validationMessages = value;
                 this.OnPropertyChanged("ValidationMessages");
            }
        }

Validate the model in any Execute method as below.
public void Execute(object parameter)
    {
         // Perform validation on the user model's built in validation.
        this.AppUser.ValidateAll();

        // Check if there are any errors.
        if (this.AppUser.HasValidationMessages<ValidationErrorMessage>())
         {
             return;
        }

         // Do stuff.
    }

In UI, define the textbox for Email and TextBlock for displaying error message if it is invalid.
<TextBox x:Name="EmailTextBox"
                    
Margin="0 5 0 0"
                    
MinWidth="200"
                    
Text="{Binding Path=AppUser.Email, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
            <TextBlock x:Name="EmailValidationErrorTextBlock"
                      
Text="{Binding Path=ValidationMessages[Email], Converter={StaticResource ValidationCollectionToSingleStringConverter}}"
                      
Foreground="Red" />


Refer the below sample for understanding more field validations.
http:// nullskull.com/FileUpload/-407123783_ValidatableBase.zip       


By Siva Jagan Dhulipalla   Popularity  (2278 Views)