Getting Started With Xamarin And Azure - Extend The Sample App - Part Two

Scope

The following article covers a presentation and demo, presented at Xamarin Dev Days in Mauritius. The article demonstrates how to get started with Azure Mobile Apps and get the benefit of the powers of the cloud in terms of Scalability, Offline Sync, and Data Analytics.

This is the second part of the series where we’ll extend the sample app, discussed in part one.

Introduction

The objective of this article is to build a sample app discussed in part 1 and add custom logic. In this demo, an app, that will allow the attendees of Xamarin Dev Days to give feedback to the organizers, will be created. The application will store the attendee name, the attendee feedback, and a sentiment score.

Modifying the Cloud Back-end

  1. Adding the Data Object

    The first step is to add the data object. Therefore, create a new file called Feedback.cs in the DataObjects folder.

    Make sure that the class inherits from EntityData from "Microsoft.Azure.Mobile.Server", and add the attributes of the model, as below.
    1. public class Feedback: EntityData {  
    2.     public string Name {  
    3.         get;  
    4.         set;  
    5.     }  
    6.     public string FeedbackText {  
    7.         get;  
    8.         set;  
    9.     }  
    10.     public double SentimentScore {  
    11.         get;  
    12.         set;  
    13.     }  
    14. }  
    modify

  2. Adding the Controller

    In the controller, the following methods will need to be added.
    modify

    Luckily, with the Microsoft Azure SDK, all the codes do not have to be typed from scratch. Instead, scaffolding can be used. Please follow the steps below to scaffold the codes for the controller.

    1. Right-click on the Controller folder and click Add > Controller.

      modify

    2. Select Azure Table App Controller and click Add.

      modify

    3. Select the Model, Context, and click Add.

      modify

    4. The following code will be automatically generated.
      1. public class FeedbackController: TableController < Feedback > {  
      2.     protected override void Initialize(HttpControllerContext controllerContext) {  
      3.         base.Initialize(controllerContext);  
      4.         devdaysblogContext context = new devdaysblogContext();  
      5.         DomainManager = new EntityDomainManager < Feedback > (context, Request);  
      6.     }  
      7.     // GET tables/Feedback  
      8.     //Select all rows from the feedback table  
      9.     public IQueryable < Feedback > GetAllFeedback() {  
      10.         return Query();  
      11.     }  
      12.     // GET tables/Feedback/48D68C86-6EA6-4C25-AA33-223FC9A27959  
      13.     // Select a specific row in the feedback table  
      14.     public SingleResult < Feedback > GetFeedback(string id) {  
      15.         return Lookup(id);  
      16.     }  
      17.     // PATCH tables/Feedback/48D68C86-6EA6-4C25-AA33-223FC9A27959  
      18.     //Update a row in the feedback table  
      19.     public Task < Feedback > PatchFeedback(string id, Delta < Feedback > patch) {  
      20.         return UpdateAsync(id, patch);  
      21.     }  
      22.     // POST tables/Feedback  
      23.     // Insert a new row in the feedback table  
      24.     public async Task < IHttpActionResult > PostFeedback(Feedback item) {  
      25.         Feedback current = await InsertAsync(item);  
      26.         return CreatedAtRoute("Tables"new {  
      27.             id = current.Id  
      28.         }, current);  
      29.     }  
      30.     // DELETE tables/Feedback/48D68C86-6EA6-4C25-AA33-223FC9A27959  
      31.     //Delete a specific row in the table  
      32.     public Task DeleteFeedback(string id) {  
      33.         return DeleteAsync(id);  
      34.     }  
      35. }  
    5. Add the migrations

      Since the code first approach is used here, code first migrations will need to be added to the project. Follow the steps here to get started with the migrations.

    6. Now that our back-end code is ready, we can deploy it to Azure App Service.

Modifying the Client App

In the portable class library, add the following.

  1. Feedback.cs class

    Add the properties that will be required to capture the feedback, the property ID to uniquely identify each record, and the property version which will be used internally by Azure App Service to keep track of which version of the record is being modified.
    1. public class Feedback {  
    2.     string id;  
    3.     string name;  
    4.     string feedbacktext;  
    5.     double sentimentscore;  
    6.     //represents the ID of the record  
    7.     [JsonProperty(PropertyName = "id")]  
    8.     public string Id {  
    9.         get {  
    10.             return id;  
    11.         }  
    12.         set {  
    13.             id = value;  
    14.         }  
    15.     }  
    16.     [JsonProperty(PropertyName = "Name")]  
    17.     public string Name {  
    18.         get {  
    19.             return name;  
    20.         }  
    21.         set {  
    22.             name = value;  
    23.         }  
    24.     }  
    25.     [JsonProperty(PropertyName = "FeedbackText")]  
    26.     public string FeedbackText {  
    27.         get {  
    28.             return feedbacktext;  
    29.         }  
    30.         set {  
    31.             feedbacktext = value;  
    32.         }  
    33.     }  
    34.     [JsonProperty(PropertyName = "SentimentScore")]  
    35.     public double SentimentScore {  
    36.         get {  
    37.             return sentimentscore;  
    38.         }  
    39.         set {  
    40.             sentimentscore = value;  
    41.         }  
    42.     }  
    43.     // used internally by Azure App Service to keep track of which version of the record I being modified.  
    44.     [Version]  
    45.     public string Version {  
    46.         get;  
    47.         set;  
    48.     }  
    49. }  
  2. Add the class FeedbackManager.cs with the following variables and methods.
    1. //singleton pattern to use only one instance of the manager  
    2. static FeedbackManager defaultInstance = new FeedbackManager();  
    3. //Provides basic access to a Microsoft Azure Mobile Service.  
    4. MobileServiceClient client;  
    5. //Provides operations on a table for a Microsoft Azure Mobile Service.  
    6. IMobileServiceTable < Feedback > feedbackTable;  
    7. //constructor - sets the client and the feedback table  
    8. private FeedbackManager() {  
    9.         this.client = new MobileServiceClient(Constants.ApplicationURL);  
    10.         this.feedbackTable = client.GetTable < Feedback > ();  
    11.     }  
    12.     //Returns the default manager. Used for the Singleton  
    13. public static FeedbackManager DefaultManager {  
    14.     get {  
    15.         return defaultInstance;  
    16.     }  
    17.     private set {  
    18.         defaultInstance = value;  
    19.     }  
    20. }  
    21. //returns the current mobile service client  
    22. public MobileServiceClient CurrentClient {  
    23.     get {  
    24.         return client;  
    25.     }  
    26. }  
    27. //retrieves the feedback from the backend  
    28. public async Task < ObservableCollection < Feedback >> GetFeedbacksAsync(bool syncItems = false) {  
    29.         try {  
    30.             IEnumerable < Feedback > items = await feedbackTable.ToEnumerableAsync();  
    31.             return new ObservableCollection < Feedback > (items);  
    32.         } catch (MobileServiceInvalidOperationException msioe) {  
    33.             Debug.WriteLine(@ "Invalid sync operation: {0}", msioe.Message);  
    34.         } catch (Exception e) {  
    35.             Debug.WriteLine(@ "Sync error: {0}", e.Message);  
    36.         }  
    37.         return null;  
    38.     }  
    39.     //save feedback item in the backend  
    40. public async Task SaveFeedbackAsync(Feedback item) {  
    41.     if (item.Id == null) {  
    42.         await feedbackTable.InsertAsync(item);  
    43.     } else {  
    44.         await feedbackTable.UpdateAsync(item);  
    45.     }  
    46. }  
  3. Add the Feedback Page

    1. XAML Snippet

      The XAML codes has 3 main parts, namely, the TextBoxes (Entry), the Add button, and a list view.
      1. <StackLayout Orientation="Vertical">  
      2.     <Entry x:Name="newItemName" Placeholder="Enter your name" />  
      3.     <Entry x:Name="newFeedbackText" Placeholder="Enter your feedback" /> </StackLayout>  
      4. <Button Text="Save" MinimumHeightRequest="30" Clicked="OnAdd" />  
      5. <ListView x:Name="todoList" IsPullToRefreshEnabled="true" Refreshing="OnRefresh" Grid.Row="1">  
      6.     <ListView.ItemTemplate>  
      7.         <DataTemplate>  
      8.             <ViewCell>  
      9.                 <StackLayout Orientation="Horizontal" HeightRequest="30">  
      10.                     <Label Text="{Binding Name}" />  
      11.                     <Label Text="{Binding FeedbackText}" /> </StackLayout>  
      12.             </ViewCell>  
      13.         </DataTemplate>  
      14.     </ListView.ItemTemplate>  
      15. </ListView>  

    2. The Feedback.xaml.cs code

      The following methods interact with the Manager Class to add and retrieve the feedback.
      1. async Task AddItem(Feedback item) {  
      2.     await manager.SaveFeedbackAsync(item);  
      3.     todoList.ItemsSource = await manager.GetFeedbacksAsync();  
      4. }  
      5. private async Task RefreshItems(bool showActivityIndicator, bool syncItems) {  
      6.     todoList.ItemsSource = await manager.GetFeedbacksAsync(syncItems);  
      7. }  
      The following code handles the events generated by the application.
      1. public async void OnAdd(object sender, EventArgs e) {  
      2.     var feedback = new Feedback {  
      3.         Name = newItemName.Text,  
      4.             FeedbackText = newFeedbackText.Text  
      5.     };  
      6.     await AddItem(feedback);  
      7.     newItemName.Text = string.Empty;  
      8.     newItemName.Unfocus();  
      9. }  
      10. public async void OnRefresh(object sender, EventArgs e) {  
      11.     var list = (ListView) sender;  
      12.     Exception error = null;  
      13.     try {  
      14.         await RefreshItems(falsetrue);  
      15.     } catch (Exception ex) {  
      16.         error = ex;  
      17.     } finally {  
      18.         list.EndRefresh();  
      19.     }  
      20.     if (error != null) {  
      21.         await DisplayAlert("Refresh Error""Couldn't refresh data (" + error.Message + ")""OK");  
      22.     }  
      23. }  
      24. public async void OnSyncItems(object sender, EventArgs e) {  
      25.     await RefreshItems(truetrue);  
      26. }  
  4. The last part is to modify the App.cs page to launch the Feedback page by default when the app launches.

    MainPage = new FeedbackPage();

  5. Run the application and test.

    modify

    You can also verify in the database. The Feedback table will be created and the new record will be inserted.

    modify

Conclusion

In this article, you saw how easily we can extend the sample application and add new features to the application by using the Azure SDK and Azure Mobile Services. In the next article, we’ll discuss how to add offline sync capabilities to the application.


Similar Articles