Xamarin.Forms Web Service Tutorial
Before attempting this tutorial, you should have successfully completed the:
- Build your first Xamarin.Forms app quickstart.
- StackLayout tutorial.
- Label tutorial.
- Button tutorial.
- CollectionView tutorial.
In this tutorial, you learn how to:
- Use the NuGet Package Manager to add Newtonsoft.Json to a Xamarin.Forms project.
- Create the web service classes.
- Consume the web service classes.
You will use Visual Studio 2019, or Visual Studio for Mac, to create a simple application that demonstrates how to retrieve .NET repository data from the GitHub web API. The retrieved data will be displayed in a CollectionView
. The following screenshots show the final application:
Add Newtonsoft.Json
To complete this tutorial you should have Visual Studio 2019 (latest release), with the Mobile development with .NET workload installed. In addition, you will require a paired Mac to build the tutorial application on iOS. For information about installing the Xamarin platform, see Installing Xamarin. For information about connecting Visual Studio 2019 to a Mac build host, see Pair to Mac for Xamarin.iOS development.
Launch Visual Studio, and create a new blank Xamarin.Forms app named WebServiceTutorial.
Important
The C# and XAML snippets in this tutorial requires that the solution is named WebServiceTutorial. Using a different name will result in build errors when you copy code from this tutorial into the solution.
For more information about the .NET Standard library that gets created, see Anatomy of a Xamarin.Forms application in the Xamarin.Forms Quickstart Deep Dive.
In Solution Explorer, select the WebServiceTutorial project, right-click and select Manage NuGet Packages...:
In the NuGet Package Manager, select the Browse tab, search for the Newtonsoft.Json NuGet package, select it, and click the Install button to add it to the project:
This package will be used to incorporate JSON deserialization into the application.
Build the solution to ensure there are no errors.
Create web service classes
REST requests are made over HTTP using the same HTTP verbs that web browsers use to retrieve pages and to send data to servers. In this exercise, you will create a class that uses the GET verb to retrieve .NET repository data from the GitHub web API.
In Solution Explorer, in the WebServiceTutorial project, add a new class named
Constants
to the project. Then, in Constants.cs, remove all of the template code and replace it with the following code:namespace WebServiceTutorial { public static class Constants { public const string GitHubReposEndpoint = "https://api.github.com/orgs/dotnet/repos"; } }
This code defines a single constant - the endpoint against which web requests will be made.
In Solution Explorer, in the WebServicesTutorial project, add a new class named
Repository
to the project. Then, in Repository.cs, remove all of the template code and replace it with the following code:using System; using Newtonsoft.Json; namespace WebServiceTutorial { public class Repository { [JsonProperty("name")] public string Name { get; set; } [JsonProperty("description")] public string Description { get; set; } [JsonProperty("html_url")] public Uri GitHubHomeUrl { get; set; } [JsonProperty("homepage")] public Uri Homepage { get; set; } [JsonProperty("watchers")] public int Watchers { get; set; } } }
This code defines a
Repository
class that's used to model the JSON data retrieved from the web service. Each property is decorated with aJsonProperty
attribute, containing a JSON field name. Newtonsoft.Json will use this mapping of JSON field names to CLR properties when deserializing the JSON data into model objects.Note
The class definition above has been simplified, and does not fully model the JSON data retrieved from the web service.
In Solution Explorer, in the WebServiceTutorial project, add a new class named
RestService
to the project. Then, in RestService.cs, remove all of the template code and replace it with the following code:using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Diagnostics; using System.Net.Http; using System.Net.Http.Headers; using System.Threading.Tasks; using Xamarin.Forms; namespace WebServiceTutorial { public class RestService { HttpClient _client; public RestService() { _client = new HttpClient(); if (Device.RuntimePlatform == Device.UWP) { _client.DefaultRequestHeaders.Add("User-Agent", ".NET Foundation Repository Reporter"); _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/vnd.github.v3+json")); } } public async Task<List<Repository>> GetRepositoriesAsync(string uri) { List<Repository> repositories = null; try { HttpResponseMessage response = await _client.GetAsync(uri); if (response.IsSuccessStatusCode) { string content = await response.Content.ReadAsStringAsync(); repositories = JsonConvert.DeserializeObject<List<Repository>>(content); } } catch (Exception ex) { Debug.WriteLine("\tERROR {0}", ex.Message); } return repositories; } } }
This code defines a single method,
GetRepositoriesAsync
, that retrieves .NET repository data from the GitHub web API. This method uses theHttpClient.GetAsync
method to send a GET request to the web API specified by theuri
argument. The web API sends a response that is stored in aHttpResponseMessage
object. The response includes a HTTP status code, which indicates whether the HTTP request succeeded or failed. Provided that the request succeeds, the web API responds with HTTP status code 200 (OK), and a JSON response, which is in theHttpResponseMessage.Content
property. This JSON data is read to astring
using theHttpContent.ReadAsStringAsync
method, before being deserialized into aList<Repository>
object using theJsonConvert.DeserializeObject
method. This method uses the mappings between JSON field names and CLR properties, that are defined in theRepository
class, to perform the deserialization.Note
On UWP, it's necessary to configure the
HttpClient
object in the constructor to add a User Agent header to all requests, and to accept GitHub JSON responses.Build the solution to ensure there are no errors.
Consume web service classes
In this exercise you will create a user interface to consume the RestService
class, which retrieves .NET repository data from the GitHub web API. The retrieved data will be displayed by a CollectionView
.
In Solution Explorer, in the WebServiceTutorial project, double-click MainPage.xaml to open it. Then, in MainPage.xaml, remove all of the template code and replace it with the following code:
<?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="WebServiceTutorial.MainPage"> <StackLayout Margin="20,35,20,20"> <Button Text="Get Repository Data" Clicked="OnButtonClicked" /> <CollectionView x:Name="collectionView"> <CollectionView.ItemTemplate> <DataTemplate> <StackLayout> <Label Text="{Binding Name}" FontSize="Medium" /> <Label Text="{Binding Description}" TextColor="Silver" FontSize="Small" /> <Label Text="{Binding GitHubHomeUrl}" TextColor="Gray" FontSize="Caption" /> </StackLayout> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView> </StackLayout> </ContentPage>
This code declaratively defines the user interface for the page, which consists of a
Button
, and aCollectionView
. TheButton
sets itsClicked
event to an event handler namedOnButtonClicked
that will be created in the next step. TheCollectionView
sets theCollectionView.ItemTemplate
property to aDataTemplate
, which defines the appearance of each item in theCollectionView
. The child of theDataTemplate
is aStackLayout
, which contains threeLabel
objects. TheLabel
objects bind theirText
properties to theName
,Description
, andGitHubHomeUrl
properties of eachRepository
object. For more information about data binding, see Xamarin.Forms Data Binding.In addition, the
CollectionView
has a name specified with thex:Name
attribute. This enables the code-behind file to access the object using the assigned name.In Solution Explorer, in the WebServiceTutorial project, expand MainPage.xaml and double-click MainPage.xaml.cs to open it. Then, in MainPage.xaml.cs, remove all of the template code and replace it with the following code:
using System; using System.Collections.Generic; using Xamarin.Forms; namespace WebServiceTutorial { public partial class MainPage : ContentPage { RestService _restService; public MainPage() { InitializeComponent(); _restService = new RestService(); } async void OnButtonClicked(object sender, EventArgs e) { List<Repository> repositories = await _restService.GetRepositoriesAsync(Constants.GitHubReposEndpoint); collectionView.ItemsSource = repositories; } } }
The
OnButtonClicked
method, which is executed when theButton
is tapped, invokes theRestService.GetRepositoriesAsync
method to retrieve .NET repository data from the GitHub web API. TheGetRepositoriesAsync
method requires astring
argument representing the URI of the web API being invoked, and this is returned by theConstants.GitHubReposEndpoint
field.After retrieving the requested data, the
CollectionView.ItemsSource
property is set to the retrieved data.In the Visual Studio toolbar, press the Start button (the triangular button that resembles a Play button) to launch the application inside your chosen remote iOS simulator or Android emulator. Tap the
Button
to retrieve .NET repository data from GitHub:In Visual Studio, stop the application.
For more information about consuming REST-based web services in Xamarin.Forms, see Consume a RESTful Web Service (guide).
Congratulations!
Congratulations on completing this tutorial, where you learned how to:
- Use the NuGet Package Manager to add Newtonsoft.Json to a Xamarin.Forms project.
- Create the web service classes.
- Consume the web service classes.
Next steps
This series of tutorials has covered the basics of creating mobile applications with Xamarin.Forms. To learn more about Xamarin.Forms development, read about the following functionality:
- There are four main control groups used to create the user interface of a Xamarin.Forms application. For more information, see Controls Reference.
- Data binding is a technique for linking properties of two objects so that changes in one property are automatically reflected in the other property. For more information, see Data Binding.
- Xamarin.Forms provides multiple page navigation experiences, depending upon the page type being used. For more information, see Navigation.
- Styles help to reduce repetitive markup, and allow an applications appearance to be more easily changed. For more information, see Styling Xamarin.Forms Apps.
- XAML markup extensions extend the power and flexibility of XAML by allowing element attributes to be set from sources other than literal text strings. For more information, see XAML Markup Extensions.
- Data templates provide the ability to define the presentation of data on supported views. For more information, see Data Templates.
- Each page, layout, and view is rendered differently on each platform using a
Renderer
class that in turn creates a native control, arranges it on the screen, and adds the behavior specified in the shared code. Developers can implement their own customRenderer
classes to customize the appearance and/or behavior of a control. For more information, see Custom Renderers. - Effects also allow the native controls on each platform to be customized. Effects are created in platform-specific projects by subclassing the
PlatformEffect
class, and are consumed by attaching them to an appropriate Xamarin.Forms control. For more information, see Effects. - Shared code can access native functionality through the
DependencyService
class. For more information, see Accessing Native Features with DependencyService.
Alternatively, Creating Mobile Apps with Xamarin.Forms, a book by Charles Petzold, is a good place to learn more about Xamarin.Forms. The book is available as a PDF or in a variety of ebook formats.
Related links
Have an issue with this section? If so, please give us some feedback so we can improve this section.