Google Fluent Validation: How to validate Registration Page fields in Xamarin Forms (C# - Xaml) | SubramanyamRaju Xamarin & Windows App Dev Tutorials

Sunday, 18 March 2018

Fluent Validation: How to validate Registration Page fields in Xamarin Forms (C# - Xaml)

Introduction:
Fluent validation is a small validation library for .NET that uses a Fluent interface and lambda expressions for building validation rules for your business objects. Fluent validation is one way of setting up dedicated validator objects, that you would use when you want to treat validation logic as separate from business logic. This article describes how to do FluentValidaiton in Xamarin.Forms for Registration Page.



Requirements:
  • This article source code is prepared by using Visual Studio Community for Mac (7.4). And it is better to install latest visual studio updates from here.
  • This sample project is Xamarin.Forms PCL project and tested in Android emulator and iOS simulators.
  • Used FluentValidation Nuget Package version is V7.5.2.
Description:
This article can explain you below topics:
1. How to create Xamarin.Forms PCL project with Visual Studio for Mac?
2. How to create RegistrationPage and bind it to view model in Xamarin.Forms PCL project?
3. How to create Fluentvalidation rules to validate registration page in Xamarin.Forms app?
4. How to call Fluentvalidation validator class from view model?
5. How to set default view model Command for Registration submit Button?

1. How to create Xamarin.Forms PCL project with Visual studio for Mac?
First we need to create the new Xamarin.Forms project. 
  • Launch Visual Studio for Mac.
  • On the File menu, select New Solution.
  • The New Project dialog appears. The left pane of the dialog lets you select the type of templates to display. In the left pane Multiplatform App Xamarin.Forms > Blank Forms App and click on Next.
  • Enter your App Name (Ex: FluentValidationSample). Select Target Platforms to Android & iOS and Shared Code to Portable Class Library  after that click on Next button.

  • You can choose your project location like below and Create new project.
And project structure will be.
  • FluentValidationSample: It is for PCL shared code.
  • FluentValidationSample.Droid: It is for Android.
  • FluentValidationSample.iOS: It is for iOS.
2. How to create RegistrationPage and bind it to view model in Xamarin.Forms PCL project?
Now create Views folder by right click on your PCL project name FluentValidationSample => Add => New Folder and name it "Views". After that right click on Views folder => Add =>New File => Forms => Forms ContentPage Xaml and name it UserRegistration like below.
UserRegistration.xaml
Now open UserRegistration.xaml page and add below xaml code to create UI for it.


  • <?xml version="1.0" encoding="UTF-8"?>  
  • <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="FluentValidationSample.Views.UserRegistration">  
  •   <ScrollView>    
  •         <StackLayout Padding="40,60,40,0" VerticalOptions="FillAndExpand" Spacing="70">    
  •             <Label Text="Fluent Validation" TextColor="Blue" HorizontalOptions="CenterAndExpand" FontSize="30"/>    
  •             <StackLayout Spacing="20">    
  •             <Entry Placeholder="User Name" Text="{Binding UserName}" HeightRequest="40" HorizontalOptions="FillAndExpand"  TextColor="Gray" BackgroundColor="White"/>    
  •             <Entry Placeholder="Phone Number" Text="{Binding PhoneNumber}" Keyboard="Telephone" HeightRequest="40" HorizontalOptions="FillAndExpand"  TextColor="Gray" BackgroundColor="White"/>    
  •             <Entry Placeholder="Email" Text="{Binding Email}" HeightRequest="40" Keyboard="Email" HorizontalOptions="FillAndExpand"  TextColor="Gray" BackgroundColor="White"/>    
  •             <Entry Placeholder="Password" IsPassword="true" Text="{Binding Password}" HeightRequest="40" HorizontalOptions="FillAndExpand"  TextColor="Gray" BackgroundColor="White"/>    
  •             <Entry Placeholder="ConfirmPassword" IsPassword="true" Text="{Binding ConfirmPassword}" HeightRequest="40" HorizontalOptions="FillAndExpand"  TextColor="Gray" BackgroundColor="White"/>    
  •             <Button Text="Register" HorizontalOptions="FillAndExpand" TextColor="Blue" Command="{Binding RegisterCommand}" HeightRequest="40"  BackgroundColor="White"/>    
  •             </StackLayout>    
  •         </StackLayout>    
  •             </ScrollView>    
  • </ContentPage>  


  • In above Xaml code, we can observe that there are five Entry fields (bind to UserName, PhoneNumber, Email, Password, ConfirmPassword) and one Button (bind to RegisterCommand). These source properties should be added in our view model.
    So create ViewModels folder, after that right click on ViewModels folder => Add =>New File => General => Empty Class and name it UserRegistrationViewModel like below.
    UserRegistrationViewModel.cs
    Now open UserRegistrationViewModel.cs file and below code:
    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.ComponentModel;  
    4. using System.Runtime.CompilerServices;  
    5. using System.Windows.Input;  
    6. using FluentValidation;  
    7. using FluentValidationSample.Models;  
    8. using Xamarin.Forms;  
    9.   
    10. namespace FluentValidationSample.ViewModels  
    11. {  
    12.     public class UserRegistrationViewModel: INotifyPropertyChanged  
    13.     {  
    14.   
    15.         public ICommand RegisterCommand { get;  set; }  
    16.         readonly IValidator _validator;  
    17.   
    18.         public UserRegistrationViewModel()  
    19.         {  
    20.             _validator = new UserValidator();  
    21.             RegisterCommand = new Command(RegisterValidation);  
    22.         }  
    23.     
    24.         void RegisterValidation()    
    25.         {    
    26.             var userObj = new UserInfo    
    27.             {    
    28.                 UserName = UserName,    
    29.                 PhoneNumber = PhoneNumber,    
    30.                 Email = Email,    
    31.                 Password = Password,    
    32.                 ConfirmPassword = ConfirmPassword,    
    33.             };    
    34.             var validationResults = _validator.Validate(userObj);    
    35.     
    36.             if (validationResults.IsValid)    
    37.             {    
    38.                 App.Current.MainPage.DisplayAlert("FluentValidation""Validation Success..!!""Ok");    
    39.             }    
    40.             else    
    41.             {    
    42.                 App.Current.MainPage.DisplayAlert("FluentValidation", validationResults.Errors[0].ErrorMessage, "Ok");    
    43.             }    
    44.         }  
    45.   
    46.         string _userName;  
    47.         public string UserName  
    48.         {  
    49.             get { return _userName; }  
    50.             set { SetProperty(ref _userName, value); }  
    51.         }  
    52.   
    53.         string _phoneNumber;  
    54.         public string PhoneNumber  
    55.         {  
    56.             get { return _phoneNumber; }  
    57.             set { SetProperty(ref _phoneNumber, value); }  
    58.         }  
    59.   
    60.         string _email;  
    61.         public string Email  
    62.         {  
    63.             get { return _email; }  
    64.             set { SetProperty(ref _email, value); }  
    65.         }  
    66.   
    67.         string _password;  
    68.         public string Password  
    69.         {  
    70.             get { return _password; }  
    71.             set { SetProperty(ref _password, value); }  
    72.         }  
    73.   
    74.         string _confirmPassword;  
    75.         public string ConfirmPassword  
    76.         {  
    77.             get { return _confirmPassword; }  
    78.             set { SetProperty(ref _confirmPassword, value); }  
    79.         }  
    80.   
    81.         protected bool SetProperty<T>(ref T backingStore, T value,  
    82.             [CallerMemberName]string propertyName = "",  
    83.             Action onChanged = null)  
    84.         {  
    85.             if (EqualityComparer<T>.Default.Equals(backingStore, value))  
    86.                 return false;  
    87.   
    88.             backingStore = value;  
    89.             onChanged?.Invoke();  
    90.             OnPropertyChanged(propertyName);  
    91.             return true;  
    92.         }  
    93.  
    94.         #region INotifyPropertyChanged    
    95.         public event PropertyChangedEventHandler PropertyChanged;  
    96.         protected void OnPropertyChanged([CallerMemberName] string propertyName = "")  
    97.         {  
    98.             var changed = PropertyChanged;  
    99.             if (changed == null)  
    100.                 return;  
    101.   
    102.             changed.Invoke(thisnew PropertyChangedEventArgs(propertyName));  
    103.         }  
    104.         #endregion  
    105.   
    106.     }  
    107. }  
    UserRegistration.xaml.cs
    Now in UserRegistration.xaml.cs, we have to set BindingContext by passing passing above view model object like below:
    1. using FluentValidationSample.ViewModels;  
    2. using Xamarin.Forms;  
    3.   
    4. namespace FluentValidationSample.Views  
    5. {  
    6.     public partial class UserRegistration : ContentPage  
    7.     {  
    8.         public UserRegistration()  
    9.         {  
    10.             InitializeComponent();  
    11.             BindingContext = new UserRegistrationViewModel();  
    12.         }  
    13.     }  
    14. }  

    3. How to create Fluentvalidation rules to validate registration page? 
    We need to follow below few steps to create FluentValidation rules in Xamarin.Forms.
    Step 1: Add FluentValidation Nuget Package:
    Right click on Packages folder => Add Packages.
    After that Add Packages windows will open, search for "FluentValidation" and click on Add Package to install it.
    Now your PCL project should include above package like below:
    Step 2: Create a Class that properties need to validate:
    Create Models folder in PCL, after that right click on Models folder => Add =>New File => General => Empty Class and name it UserInfo like below.
    UserInfo.cs

    Open UnserInfo file and add below properties:


  • using System;  
  • namespace FluentValidationSample.Models  
  • {  
  •     public class UserInfo  
  •     {  
  •         public string UserName { getset; }  
  •         public string PhoneNumber { getset; }  
  •         public string Email { getset; }  
  •         public string Password { getset; }  
  •         public string ConfirmPassword { getset; }  
  •     }  
  • }  
  • Step 3: Create a Class that should have validation rules:
    In Models folder, create a class that should inherit the AbstractValidator class with the type UserInfo class like below:
    UserValidator.cs
    1. using FluentValidation;  
    2.   
    3. namespace FluentValidationSample.Models  
    4. {  
    5.     public class UserValidator : AbstractValidator<UserInfo>  
    6.     {  
    7.         public UserValidator()  
    8.         {  
    9.             RuleFor(x => x.UserName).NotNull().Length(8, 20);  
    10.             RuleFor(x => x.PhoneNumber).NotNull().MinimumLength(10);  
    11.             RuleFor(x => x.Email).NotNull().EmailAddress().WithMessage("Invalid Email.");  
    12.             RuleFor(x => x.Password).NotNull().Length(8);  
    13.             RuleFor(x => x.ConfirmPassword).NotNull().Equal(x => x.Password);  
    14.         }  
    15.     }  
    16. }  
    In above class, we can see there is list of rules to validate UserInfo object properties:
    • UserName: It should not be null and user name length should between 8 to 20 characters.
    • Phone Number: It should not be nulll and minimum length should be 10 characters.
    • Email: It should not be null and it should have a email format.
    • PasswordIt should not be nulll and length should be equal to 8 characters.
    • ConfirmPasswordIt should not be nulll and string should be equal to password value string.

    4. How to call Fluentvalidation validator class from view model?
    In above step, we have completed validator class rules and now we have to learn to use.
    So in our view model constructor create object for IValidator which will define validator for particular type.
    1. readonly IValidator _validator;  
    2. public UserRegistrationViewModel() {  
    3.    _validator = new UserValidator();  
    4. }  
    Now create UserInfo object and set user input values for it and pass it to IValidator Validate method like below
    1. void ValidateUserInfo()    
    2.         {    
    3.             var userObj = new UserInfo    
    4.             {    
    5.                 UserName = UserName,    
    6.                 PhoneNumber = PhoneNumber,    
    7.                 Email = Email,    
    8.                 Password = Password,    
    9.                 ConfirmPassword = ConfirmPassword,    
    10.             };    
    11.             var validationResults = _validator.Validate(userObj);    
    12.     
    13.             if (validationResults.IsValid)    
    14.             {    
    15.                 App.Current.MainPage.DisplayAlert("FluentValidation""Validation Success..!!""Ok");    
    16.             }    
    17.             else    
    18.             {    
    19.                 App.Current.MainPage.DisplayAlert("FluentValidation", validationResults.Errors[0].ErrorMessage, "Ok");    
    20.             }    
    21.         }  
    5. How to set default view model Command for Registration submit Button Submit?
    When user fill all fields and tap on Register button to submit form, we need to invoke above ValidateUserInfo method which was declared in view model. So we have to create Icommand property that should invoke the method like below:
    1. public ICommand RegisterCommand { get;  set; }  
    2. readonly IValidator _validator;  
    3.   
    4. public UserRegistrationViewModel()  
    5. {  
    6.     _validator = new UserValidator();  
    7.     RegisterCommand = new Command(RegisterValidation);  
    8. }  
    9.   
    10. void RegisterValidation()    
    11. {    
    12.     var userObj = new UserInfo    
    13.     {    
    14.         UserName = UserName,    
    15.         PhoneNumber = PhoneNumber,    
    16.         Email = Email,    
    17.         Password = Password,    
    18.         ConfirmPassword = ConfirmPassword,    
    19.     };    
    20.     var validationResults = _validator.Validate(userObj);    
    21.   
    22.     if (validationResults.IsValid)    
    23.     {    
    24.         App.Current.MainPage.DisplayAlert("FluentValidation""Validation Success..!!""Ok");    
    25.     }    
    26.     else    
    27.     {    
    28.         App.Current.MainPage.DisplayAlert("FluentValidation", validationResults.Errors[0].ErrorMessage, "Ok");    
    29.     }    
    30. }  
    Also in our xaml code, for Register button we need to bind above ICommand like below:
    1. <Button Text="Register" HorizontalOptions="FillAndExpand" TextColor="Blue" Command="{Binding RegisterCommand}" HeightRequest="40"  BackgroundColor="White"/>    

    Demo screens from Android:
    Demo screens from iOS:
    You can directly work on below sample source code to understand the this article. 

    CheckBoxSample

    FeedBack Note: Please share your thoughts, what you think about this post, Is this post really helpful for you? Otherwise, it would be very happy, if you have any thoughts for to implement this requirement in any other way? I always welcome if you drop comments on this post and it would be impressive.

    Follow me always at @Subramanyam_B
    Have a nice day by  :)

    2 comments:

    Search Engine Submission - AddMe