Using HttpClient with Xamarin.Forms

One can say Mobile Applications today cannot exist without a connected backend. Unless, you are building a calculator like app there’s a need for every app to connect to server to retrieve user’s data. In this post, I will show how we can use HttpClient module to make REST API calls in the Xamarin.Forms application.

In this post, I will be creating a simple ToDo app that:

  1. Adds a new item to server data
  2. Fetches existing items from server
  3. Update an existing item
  4. Delete an item

The sample can be opened in Xamarin Studio or Visual Studio. For simplicity, I have used Xamarin Studio here. Feel free to use the IDE of your choice, when you give it a try.

Step 1 : Create a Xamarin.Forms application

Open Xamarin Studio, File -> New Solution -> Under Multiplatform App -> Xamarin.Forms -> Forms App

Follow the steps and create a new project. Just to make sure, everything works fine. Build and run the app in iOS/Android. The finished project's folder structure would look like below :

Step 2 : Write REST API Invocation code in the PCL project - HttpClientDemo

  • Install the package Microsoft.Net.Http from Nuget -> For making REST API calls

  • Install the package Newtonsoft.Json from Nuget -> For Serialization/Deserialization of objects

  • Create a new file TodoItem.cs with the below lines of code

using System;  
namespace HttpClientDemo.Models  
{
    public class TodoItem
    {
        public string Description { get; set; }
        public string DueDate { get; set; }
        public bool isDone { get; set; }
    }
}
  • Add a new DataService class that is responsible for making API calls
HttpGet Request

HttpClient class exposes a method called GetStringAsync to make the get requests. Lets make use of them and invoke our API. The method to invoke get requests will look like below :

/// <summary>
/// Gets the todo items async.
/// </summary>
/// <returns>The todo items async.</returns>
public async Task<List<TodoItem>> GetTodoItemsAsync()  
    {
    var response = await client.GetStringAsync("http://localhost:5000/api/todo/items");
    var todoItems = JsonConvert.DeserializeObject<List<TodoItem>>(response);
return todoItems;  
    }

The async and await operators are very handy in making asynchronous calls. Similarly the other Http operations like Post/Put/Delete can be invoked using the below methods

HttpPost Request

Similar to GetStringAsync method, we also have PostAsync method which we can leverage for making Post requests. Sample code below :

/// <summary>
/// Adds the todo item async.
/// </summary>
/// <returns>The todo item async.</returns>
/// <param name="itemToAdd">Item to add.</param>
public async Task<int> AddTodoItemAsync(TodoItem itemToAdd)  
{
   var data = JsonConvert.SerializeObject(itemToAdd);
   var content = new StringContent(data, Encoding.UTF8, "application/json");
   var response = await client.PostAsync("http://localhost:5000/api/todo/item", content);
   var result = JsonConvert.DeserializeObject<int>(response.Content.ReadAsStringAsync().Result);
   return result;
}
HttpPut Request

When we have to modify any existing item, we should be using HttpPut method. Invoking a put method is as easy as using PutAsync method from HttpClient library. Sample code below :

/// <summary>
/// Updates the todo item async.
/// </summary>
/// <returns>The todo item async.</returns>
/// <param name="itemIndex">Item index.</param>
/// <param name="itemToUpdate">Item to update.</param>
public async Task<int> UpdateTodoItemAsync(int itemIndex, TodoItem itemToUpdate)  
{
   var data = JsonConvert.SerializeObject(itemToUpdate);
   var content = new StringContent(data, Encoding.UTF8, "application/json");
   var response = await client.PutAsync(string.Concat("http://localhost:5000/api/todo/", itemIndex), content);
   return JsonConvert.DeserializeObject<int>(response.Content.ReadAsStringAsync().Result);        }
HttpDelete Request

In our sample, to delete the unwanted To-do items, we can make HttpDelete request to the API. Sample code to do that is given below:

/// <summary>
/// Deletes the todo item async.
/// </summary>
/// <returns>The todo item async.</returns>
/// <param name="itemIndex">Item index.</param>
public async Task DeleteTodoItemAsync(int itemIndex)  
{
   await client.DeleteAsync(string.Concat("http://localhost:5000/api/todo/", itemIndex));
}

Step 3 : Consume the above changes in the HttpClientDemoPage.xaml.cs file

Add a method that makes the call to the DataService to load data

async void RefreshData()  
{
       items = await dataService.GetTodoItemsAsync();           
       todoList.ItemsSource = items.OrderBy(item =>         item.isDone).ThenBy(item => item.DueDate).ToList();
}

Invoke this RefreshData function from the Constructor to load the data from service on app launch.

public HttpClientDemoPage()  
        {
            InitializeComponent();
            dataService = new DataService();
            RefreshData();
        }

Similarly, we can make appropriate calls to the Add/Update/Delete methods depending on the UI events we wish.

  • Code to add a new todo Item
async void AddButton_Clicked(object sender, System.EventArgs e)  
{
     TodoItem newItem = new TodoItem
     {
    Description = txtTodoItem.Text.Trim(),
    DueDate = dpDueDate.Date.ToString("d")
     };
     await dataService.AddTodoItemAsync(newItem);
     RefreshData();
}
  • Updating a task as done
public async void OnDone(object sender, EventArgs e)  
{
  var mi = ((MenuItem)sender);
   TodoItem itemToUpdate = (TodoItem)mi.CommandParameter;
  itemToUpdate.isDone = true;
  int itemIndex = items.IndexOf(itemToUpdate);
  await dataService.UpdateTodoItemAsync(itemIndex,itemToUpdate);
  RefreshData();
}
  • Deleting the task
public async void OnDelete(object sender, EventArgs e)  
{
   var mi = ((MenuItem)sender);
   TodoItem itemToDelete = (TodoItem)mi.CommandParameter;
   int itemIndex = items.IndexOf(itemToDelete);
   await dataService.DeleteTodoItemAsync(itemIndex);
   RefreshData();
}

That's pretty much it from the code changes. The complete source code is available in Github repo.

https://github.com/svswaminathan/xamarin-forms-httpclient-sample

The repo contains code for both the Web API (built on asp.net core) and the Xamarin Forms app. The readme file contains instructions for running both the API and the App. The finished app should work as shown in the video below:

Though HttpClient is very easy to use and does the job in most cases, to gain more advantage of the platform specific network libraries, ModernHttpClient can be used. More on that on a separate blog post soon!