Posts in Category: C#

Validation in Xamarin.Forms Enterprise Apps 

animation We released an eBook this past May on Enterprise Application Patterns using Xamarin.Forms. The eBook focuses on core patterns and architectural guidance for developing Xamarin.Forms enterprise apps that are easier to test, maintain, and evolve. Guidance is provided on how to implement the Model-View-ViewModel (MVVM) pattern, dependency injection, navigation, validation, and configuration management, while maintaining loose coupling. In addition, there’s also guidance on performing authentication and authorization with IdentityServer, accessing remote data from containerized microservices, and unit testing.

This blog post explores validation in Xamarin.Forms enterprise apps. There are, of course, many approaches that can be taken to validation. What’s presented here is the validation approach taken in the eShopOnContainers mobile app, which is extensible, easily unit testable, and supports data binding and property change notification.

Introduction

Any app that accepts input from users should ensure that the input is valid. An app could, for example, check for input that contains only characters in a particular range, is of a certain length, or matches a particular format. Without validation, a user can supply data that causes the app to fail. Validation enforces business rules, and prevents an attacker from injecting malicious data.

In the context of the Model-ViewModel-Model (MVVM) pattern, a view model or model will often be required to perform data validation and signal any validation errors to the view so that the user can correct them. The eShopOnContainers mobile app performs synchronous client-side validation of view model properties and notifies the user of any validation errors by highlighting the control that contains the invalid data, and by displaying error messages that inform the user of why the data is invalid. The following diagram shows the classes involved in performing validation in the eShopOnContainers mobile app:

View model properties that require validation are of type ValidatableObject<T>, and each ValidatableObject<T> instance has validation rules added to its Validations property. Validation is invoked from the view model by calling the Validate method of the ValidatableObject<T> instance, which retrieves the validation rules and executes them against the ValidatableObject<T> Value property. Any validation errors are placed into the Errorsproperty of the ValidatableObject<T> instance, and the IsValid property of the ValidatableObject<T> instance is updated to indicate whether validation succeeded or failed.

Property change notification is provided by the ExtendedBindableObject class, and so an Entrycontrol can bind to the IsValid property of the ValidatableObject<T> instance in the view model class to be notified of whether or not the entered data is valid.

Specifying Validation Rules

Validation rules are specified by creating a class that derives from the IValidationRule<T>interface, which is shown in the following code example:

 

public interface IValidationRule<T>
{
    string ValidationMessage { get; set; }
    bool Check(T value);
}

 

This interface specifies that a validation rule class must provide a boolean Check method that is used to perform the required validation, and a ValidationMessage property whose value is the validation error message that will be displayed if validation fails.

The following code example shows the IsNotNullOrEmptyRule<T> validation rule, which is used to perform validation of the username and password entered by the user on the LoginView when the eShopOnContainers mobile app is configured to use mock services:

 

public class IsNotNullOrEmptyRule<T> : IValidationRule<T>
{
    public string ValidationMessage { get; set; }
    public bool Check(T value)
    {
        if (value == null)
        {
            return false;
        }
        var str = value as string;
        return !string.IsNullOrWhiteSpace(str);
    }
}

 

The Check method returns a boolean indicating whether the value argument is null, empty, or consists only of whitespace characters.

Adding Validation Rules to a Property

In the eShopOnContainers mobile app, view model properties that require validation are declared to be of type ValidatableObject<T>, where T is the type of the data to be validated. The following code example shows an example of one such property:

 

public ValidatableObject<string> UserName
{
    get
    {
        return _userName;
    }
    set
    {
        _userName = value;
        RaisePropertyChanged(() => UserName);
    }
}

 

For validation to occur, validation rules must be added to the Validations collection of the ValidatableObject<T> instance, as demonstrated in the following code example:

 

private void AddValidations()
{
    _userName.Validations.Add(new IsNotNullOrEmptyRule<string> 
    { 
        ValidationMessage = "A username is required." 
    });
}

 

This method adds the IsNotNullOrEmptyRule<T> validation rule to the Validations collection of the ValidatableObject<T> instance, including a value for the ValidationMessage property, which specifies the validation error message that will be displayed if validation fails.

Triggering Validation

Validation can be triggered manually for a view model property. For example, this occurs in the eShopOnContainers mobile app when the user taps the Login button on the LoginView, when using mock services. The command delegate calls the MockSignInAsync method in the LoginViewModel, which invokes validation by executing the Validate method, which in turn invokes the ValidateUserName method:

 

private bool ValidateUserName()
{
    return _userName.Validate();
}

 

The ValidateUserName method performs validation of the username entered by the user on the LoginView, by invoking the Validate method on the ValidatableObject<T> instance. The following code example shows the Validate method from the ValidatableObject<T> class:

 

public bool Validate()
{
    Errors.Clear();
    IEnumerable<string> errors = _validations
        .Where(v => !v.Check(Value))
        .Select(v => v.ValidationMessage);
    Errors = errors.ToList();
    IsValid = !Errors.Any();
    return this.IsValid;
}

 

This method clears the Errors collection, and then retrieves any validation rules that were added to the object’s Validations collection. The Check method for each retrieved validation rule is executed, and the ValidationMessage property value for any validation rule that fails to validate the data is added to the Errors collection of the ValidatableObject<T> instance. Finally, the IsValid property is set, and its value is returned to the calling method, indicating whether validation succeeded or failed.

Validation is also automatically triggered whenever a bound property changes. For more information, see Triggering Validation when Properties Change.

Displaying Validation Errors

The eShopOnContainers mobile app notifies the user of any validation errors by highlighting the control that contains the invalid data with a red line, and by displaying an error message that informs the user why the data is invalid below the control containing the invalid data. The following screenshot shows part of the LoginView in the eShopOnContainers mobile app when a validation error is present:

Highlighting a Control that Contains Invalid Data

The LineColorBehavior attached behavior is used to highlight Entry controls where validation errors have occurred. The following code example shows how the LineColorBehavior attached behavior is attached to an Entry control:

 

<Entry Text="{Binding UserName.Value, Mode=TwoWay}">
    <Entry.Style>
        <OnPlatform x:TypeArguments="Style"
          iOS="{StaticResource EntryStyle}"
          Android="{StaticResource EntryStyle}"
          WinPhone="{StaticResource UwpEntryStyle}"/>
    </Entry.Style>
    ...
</Entry>

 

The Entry control consumes an explicit style, which is shown in the following code example:

 

<Style x:Key="EntryStyle"
       TargetType="{x:Type Entry}">
    ...
    <Setter Property="behaviors:LineColorBehavior.ApplyLineColor"
            Value="True" />
    <Setter Property="behaviors:LineColorBehavior.LineColor"
            Value="{StaticResource BlackColor}" />
    ...
</Style>

 

This style sets the ApplyLineColor and LineColor attached properties of the LineColorBehaviorattached behavior on the Entry control. When the value of the ApplyLineColor attached property is set, or changes, the LineColorBehavior attached behavior executes the OnApplyLineColorChanged method, which adds or removes the EntryLineColorEffect class to the Entry‘s Effects collection. For more information about the EntryLineColorEffect class, see Highlighting a Control that Contains Invalid Data.

The Entry control also has a DataTrigger added to its Triggers collection. The following code example shows the DataTrigger:

 

<Entry Text="{Binding UserName.Value, Mode=TwoWay}">
    ...
    <Entry.Triggers>
        <DataTrigger 
            TargetType="Entry"
            Binding="{Binding UserName.IsValid}"
            Value="False">
            <Setter Property="behaviors:LineColorBehavior.LineColor" 
                    Value="{StaticResource ErrorColor}" />
        </DataTrigger>
    </Entry.Triggers>
</Entry>

 

This DataTrigger monitors the UserName.IsValid property, and if it’s value becomes false, it executes the Setter, which changes the LineColor attached property of the LineColorBehaviorattached behavior to red.

Displaying Error Messages

The UI displays validation error messages in Label controls below each control whose data failed validation. The following code example shows the Label that displays a validation error message if the user has not entered a valid username:

 

<Label Text="{Binding UserName.Errors, Converter={StaticResource FirstValidationErrorConverter}"
       Style="{StaticResource ValidationErrorLabelStyle}" />

 

Each Label binds to the Errors property of the view model object that’s being validated. The Errors property is provided by the ValidatableObject<T> class, and is of type List<string>. Because the Errors property can contain multiple validation errors, the FirstValidationErrorConverter instance is used to retrieve the first error from the collection for display.

Summary

Enterprise Application Patterns using Xamarin.Forms focuses on core patterns and architectural guidance for developing Xamarin.Forms enterprise apps that are easier to test, maintain, and evolve. The eBook also ships with a sample application, the eShopOnContainers mobile app, which performs synchronous client-side validation of view model properties and notifies the user of any validation errors by highlighting the control that contains the invalid data, and by displaying error messages that inform the user why the data is invalid.

The post Validation in Xamarin.Forms Enterprise Apps appeared first on Xamarin Blog.

Posted by Andrew Tierney Friday, August 18, 2017 10:41:00 PM Categories: C# Xamarin

Adding Storage to Mobile Apps with OneDrive for Business 

Every app needs storage, whether it’s for storing a collection of the same type of records in Azure Mobile Service with Easy Tables, or a SQL Database exposed via Web Services. When the data is unstructured, NoSQL with Azure DocumentDB can be used. For scalability and high availability, Azure CosmosDb can be used in both the cases. In enterprise situations, however, where different types of documents need to be stored and shared with colleagues, the best solution is OneDrive for Business. OneDrive for Business is part of Office 365 and provides easy access across multiple Office 365 services. We learned previously how to integrate OneDrive for Business in mobile apps developed using Xamarin.

Since then, there have been changes to APIs and SDKs that have made this integration simpler. We’ll take a look at those changes in this blog post. You can find the repo for this post on GitHub.

Step 1: App Registration

To integrate OneDrive for Business with mobile apps, the app needs to be registered with the Azure Active Directory service. This will authenticate and authorize users while providing access to the resources. The process is the same as registering any other app with Azure Active Directory.

Visit https://apps.dev.microsoft.com/ and click on Add an app to get started. Name your app and continue, making sure you note the Application Id. Click on Add Platorm and select Native Application.

Ensure you define Delegated Permissions for the application to be able to access files stored on OneDrive for Business:

  • Files.Read
  • Files.Read.All
  • Files.Read.Selected
  • Files.ReadWrite
  • Files.ReadWrite.All
  • User.Read

Step 2: Calling APIs

Once the app is registered, create a Blank Xamarin.Forms application with the PCL code sharing strategy. Make sure that the profile selected for PCL is set to Profile7 by right-clicking the PCL project and selecting Properties > Build > General. Add two NuGet packages: Microsoft.Identity.Client and Microsoft.Graph.

Use the Microsoft Authentication Library (MSAL) to authenticate the user in the code-behind in App.xaml.cs.

 

using Microsoft.Identity.Client;
...
public static PublicClientApplication IdentityClientApp = null;
public static string ClientID = "4f91166f-c946-438f-8d07-33792251026d";
public static string[] Scopes = { "User.Read", "User.ReadBasic.All", "Files.Read", "Files.Read.All", "Files.ReadWrite", "Files.ReadWrite.All" };
public static UIParent UiParent = null;
public App()
{
   InitializeComponent();
   MainPage = new XamarinDrive.MainPage();
   IdentityClientApp = new PublicClientApplication(ClientID);
   MainPage = new NavigationPage(new MainPage());
}

 

After the authentication process is complete, create a GraphServiceClient object which will be responsible for further requests in the code-behind for MainPage.xaml.cs.

 

using Microsoft.Graph;
using Microsoft.Identity.Client;
...
private async Task CreateGraphClientAsync()
{
   try {
      Client = new GraphServiceClient("https://graph.microsoft.com/v1.0",
               new DelegateAuthenticationProvider(
               async (requestMessage) =&gt; {
                         var tokenRequest = await App.IdentityClientApp.AcquireTokenAsync(App.Scopes, App.UiParent).ConfigureAwait(false);
                         requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", tokenRequest.AccessToken);
                }));
                Me = await Client.Me.Request().GetAsync();
                Username.Text = $"Welcome {((User)Me).DisplayName}";
                return true;
       }
       catch (MsalException ex){
            await DisplayAlert("Error", ex.Message, "OK", "Cancel");
            return false;
       }
}

 

Using this GraphServiceClient and Graph Model, traverse through the Drive and get a list of items (files and folders) within the drive. Assign this list of items to the listview control in ListPage.xaml.cs.

 

using Microsoft.Graph;
...
var client = new GraphServiceClient("https://graph.microsoft.com/v1.0",
                new DelegateAuthenticationProvider(
                async (requestMessage) =&gt;
                {
                   var tokenRequest = await App.IdentityClientApp.AcquireTokenSilentAsync(App.Scopes, App.IdentityClientApp.Users.FirstOrDefault());
                   requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", tokenRequest.AccessToken);
                }));
var data = await client.Me.Drive.Root.Children.Request().GetAsync();
var list = data.ToList();
FileList.ItemsSource = list;

 

This list of DriveItems will then be displayed on ListPage using the binding with ListView. When a user clicks on an item inside List, the file will be opened as requested. This can be achieved with the OnItemTapped event.

 

var item = ((DriveItem) e.Item);
   if (item.Folder != null)
      await DisplayAlert("Type", "Selected Item is a Folder!", "Ok");
   else
      Xamarin.Forms.Device.OpenUri(new Uri(item.WebUrl));

 

Just like any Xamarin.Forms app is required to implement platform-specific functionality differently, follow the guide for each individual platform to implement authentication from here.

Step 3: Running the App

Run the app on a device or simulator and log in with your Office 365 credentials. The app will ask for appropriate permissions. Once those permissions are granted, the app will display the list of files.

Wrapping Up

OneDrive for Business, which is part of Office 365, allows users to store, share, and collaborate with different types of documents. Using Microsoft Graph Client Libraries and Microsoft Authentication Library, it’s easy to integrate various Office 365 services such as OneDrive. As usual, you can find the sample used in this blog post on GitHub.

The post Adding Storage to Mobile Apps with OneDrive for Business appeared first on Xamarin Blog.

Posted by Andrew Tierney Friday, August 18, 2017 10:39:00 PM Categories: C# Xamarin

Syncfusion Essential Studio 2017 Vol 3 

Syncfusion

RELEASE HIGHLIGHTS

Xamarin.Forms

Build Cross-Platform Apps

  • New picker control
  • New radial menu control
  • Text selection and copy support in PDF Viewer

Learn More »

Xamarin.Android

Develop Amazing Android Applications with C#

  • New picker control
  • New data form control
  • Table summaries for data grid

Learn More »

Xamarin.iOS

Create World-Class iOS Apps with C#

  • New picker control
  • New data form control
  • Table summaries for data grid

Learn More »

ASP.NET Core

Publish Superior Web Applications

  • New radial menu
  • Stacking spline area and 100% stacking spline area charts
  • Ruler support for diagram

Learn More »

ASP.NET MVC

Build Powerful Web Apps

  • Stacking spline area and 100% stacking spline area charts
  • Ruler support for diagram
  • Work week support for Gantt control

Learn More »

ASP.NET Web Forms

Master Web Development

  • New date range picker
  • Stacking spline area and 100% stacking spline area chart types
  • Ruler support for diagram

Learn More »

UWP

Develop Across the Windows Ecosystem

  • New picker control
  • Axis scale break for charts
  • Style customization support for Gantt control

Learn More »

JavaScript

Get the Most out of JavaScript

  • Stacking spline area and 100% stacking spline area charts
  • Ruler support for diagram
  • Work week support for Gantt control

Learn More »

Windows Forms

Create Better Apps

  • Content control support for DocIO
  • Customization support for message boxes
  • Tagged PDF support

Learn More »

WPF

Take Control of the Desktop

  • Themes support for tree grids
  • Axis scale break for charts
  • Report Viewer parameter rending based on parameter layout

Learn More »

Dashboard Platform

Build Better Dashboards

  • Multi-dashboard organization
  • Filter widget sliding panel
  • Data notifications
  • Personalized home pages

Learn More »

Report Platform

Create, Manage, and Share Reports

  • SSO login support using Azure ADFS
  • Microsoft Azure support for Report Server
  • Parameter layout support

Learn More »

Big Data Platform

Master Large Data Sets

  • Mobius integration
  • Faster access to YARN memory changes
  • Editable PostgreSQL credentials

Learn More »

Data Integration Platform

Do More with Data

  • User-friendly UI
  • Publishing template
  • Brand new processors

Learn More »

Posted by Andrew Tierney Friday, August 11, 2017 10:06:00 PM Categories: C# Syncfusion