Repository navigation
6. Tutorial Lab
Watch the walkthrough here.
This video demonstrates how to complete the hands-on portion of the training module.
After downloading the provided starter project, open the project in Visual Studio and build the application to make sure the starter project runs without errors.
Important: This lab does not require an Open-Meteo NuGet package. The application communicates with Open-Meteo using C#'s built-in HttpClient and reads the JSON response using System.Text.Json.
The first step is to create a model that will hold the weather information returned by the Open-Meteo API.
A model is a C# class used to represent and organize data in your application. In this project, the WeatherData model will represent the information we receive from Open-Meteo, such as the latitude, longitude, temperature, humidity, and wind speed.
Step 1 — Create the Models Folder
In Solution Explorer, locate the WeatherTraining project.
- Right-click 'WeatherTraining'.
- Select Add, then click 'New Folder'.
- Name the folder 'Models'
- Right-click your 'Models' Folder
- Select Add, then click on 'Class'
- Name the class 'WeatherData.cs'
Your project should look similar to:
The following code will go into the model you just created:
using System.Text.Json.Serialization;
namespace WeatherTraining.Models;
public class WeatherData
{
[JsonPropertyName("latitude")]
public double Latitude { get; set; }
[JsonPropertyName("longitude")]
public double Longitude { get; set; }
[JsonPropertyName("current")]
public CurrentWeather Current { get; set; } = new();
}
public class CurrentWeather
{
[JsonPropertyName("temperature_2m")]
public double Temperature { get; set; }
[JsonPropertyName("relative_humidity_2m")]
public double Humidity { get; set; }
[JsonPropertyName("wind_speed_10m")]
public double WindSpeed { get; set; }
}Here is how the code should look in Visual Studio Code:
Now that we have created a model to hold our weather data, we need a way for our application to communicate with the Open-Meteo API.
We will create a weather service that is responsible for sending requests to Open-Meteo and receiving the weather information from the API.
A service is a class that handles a specific task for our application. In this project, the WeatherService will handle communication with the weather API.
In Solution Explorer, locate the WeatherTraining project.
- Right-click 'WeatherTraining' like you did in the previous step.
- Select Add, then click New Folder.
- Name the folder 'Services'
- Right-Click on your Services Folder
- Select Add, then click 'Class'
- Name the class "WeatherService.cs"
Your project should look similar to:
The following code will go into the Service you just created:
using System.Net.Http;
using System.Text.Json;
using WeatherTraining.Models;
namespace WeatherTraining.Services;
public class WeatherService
{
private readonly HttpClient _httpClient;
public WeatherService()
{
_httpClient = new HttpClient();
}
}Here is how the code should look in Visual Studio Code:
Now that we have created the WeatherService, we can create the request that our application will send to Open-Meteo.
An API request tells a web API what information our application wants. In this project, we will use the user's latitude and longitude to request current weather information.
Our request will ask Open-Meteo for:
Temperature
Humidity
Wind speed
We will also request the temperature in Fahrenheit and wind speed in miles per hour.
Open your WeatherService.cs file.
Inside the WeatherService class, below the constructor, add the following method:
public async Task<WeatherData> GetWeatherAsync(double latitude, double longitude)
{
}The latitude and longitude parameters allow the method to request weather for different locations.
For example, when the user selects Detroit, MI, the coordinates from the main page will be passed into this method.
Inside the GetWeatherAsync method, create a string named url:
string url =
$"https://api.open-meteo.com/v1/forecast" +
$"?latitude={latitude}" +
$"&longitude={longitude}" +
$"¤t=temperature_2m,relative_humidity_2m,wind_speed_10m" +
$"&temperature_unit=fahrenheit" +
$"&wind_speed_unit=mph" +
$"&timezone=auto";This creates the URL that will be sent to Open-Meteo.
Inside the GetWeatherAsync method, locate the API URL you created in Part 4, and driectly underneath it (Still inside the method) add the following code:
HttpResponseMessage response = await _httpClient.GetAsync(url);The GetAsync() method sends an HTTP GET request to the URL we created.
A GET request is used when we want to retrieve information from an API.
The response from the API is stored in the response variable.
Under the request, add:
response.EnsureSuccessStatusCode();This checks whether the API request was successful.
If Open-Meteo returns a successful HTTP status code, the program can continue.
If the request fails, EnsureSuccessStatusCode() will throw an exception. Our MainPage.xaml.cs already contains error handling that can catch this type of problem.
Your WeatherService.cs should now look like this:
Now that our application can send the API request, we need to read the response that Open-Meteo sends back.
Open-Meteo returns the weather information in JSON (JavaScript Object Notation) format. JSON is a common format used by APIs to organize and exchange data.
In this step, we will:
- Read the response from Open-Meteo.
- Store the JSON response as a string.
- Convert the JSON into our WeatherData model.
- Return the weather data to the application.
Inside the GetWeatherAsync method, locate the code you added in Part 5, and driectly underneath it (Still inside the method) add the following code:
string json = await response.Content.ReadAsStringAsync();ReadAsStringAsync() reads the contents of the API response and stores it as a string.
For example, Open-Meteo may return JSON similar to:
{
"latitude": 42.3314,
"longitude": -83.0458,
"current": {
"temperature_2m": 68.5,
"relative_humidity_2m": 54,
"wind_speed_10m": 8.2
}
}At this point, the response is simply text stored in the json variable. We still need to convert it into something our C# application can easily work with.
Below the code you just added, enter:
WeatherData? weather = JsonSerializer.Deserialize<WeatherData>(json);This process is called deserialization.
Deserialization converts the JSON response into an instance of our WeatherData class.
Remember the model we created in Part 2:
[JsonPropertyName("temperature_2m")]
public double Temperature { get; set; }The [JsonPropertyName] attribute tells the JsonSerializer which JSON property should be placed into each C# property.
Finally, add the following code underneath the deserialization code:
return weather ?? throw new Exception("Unable to read weather data.");This returns the WeatherData object to the part of the application that called GetWeatherAsync().
The ?? operator checks whether weather contains a value. If the JSON could not be converted into a WeatherData object, the application throws an exception instead.
Your finished code should look similar to:

Our application can now send a request to Open-Meteo, receive the JSON response, and convert that response into our WeatherData model.
The final step is to take that weather information and display it on the application's interface.
We will update MainPage.xaml.cs so that the values returned from the API are placed into the labels we created in the starter project.
In Solution Explorer, open "MainPage.xaml.cs"
The starter project already contains the GetWeatherButton_Clicked method. This method runs when the user clicks the Get Weather button.
Inside this method, we already validate the latitude and longitude.
After the validation, locate the following code:
WeatherData weather =
await _weatherService.GetWeatherAsync(latitude, longitude);This line calls our WeatherService and waits for the weather information to be returned.
The returned data is stored in the weather variable.
Directly underneath the GetWeatherAsync line, add:
LocationLabel.Text =
$"Location: {weather.Latitude:F2}, {weather.Longitude:F2}";
TemperatureLabel.Text =
$"{weather.Current.Temperature:F1}°F";
HumidityLabel.Text =
$"{weather.Current.Humidity:F0}%";
WindLabel.Text =
$"{weather.Current.WindSpeed:F1} mph";These lines take the values from the WeatherData object and place them into the labels created in MainPage.xaml.
LocationLabel displays the latitude and longitude.
TemperatureLabel displays the current temperature.
HumidityLabel displays the current humidity.
WindLabel displays the current wind speed.
The formatting codes control how many decimal places are displayed:
F2 = 2 decimal places
F1 = 1 decimal place
F0 = no decimal places
Your code should now look something like this:
The Open-Meteo API can provide many different types of weather information. In this activity, you will add weather code to the application.
The weather code is a numerical value provided by Open-Meteo that represents the current weather condition, such as clear skies, rain, snow, or thunderstorms.
To display a new weather variable, you need to update three parts of the application:
- The API request must ask for the new variable.
- The WeatherData model must have a property for the new value.
- The XAML page must have a place to display it.
This demonstrates an important concept when working with APIs: adding new data usually requires updating both the request and the code that handles the response.
Open Services → WeatherService.cs.
Find the current section of the API URL:
¤t=temperature_2m,relative_humidity_2m,wind_speed_10mAdd weather_code to the list:
¤t=temperature_2m,relative_humidity_2m,wind_speed_10m,weather_codeYour updated URL should look like:
string url =
$"https://api.open-meteo.com/v1/forecast" +
$"?latitude={latitude}" +
$"&longitude={longitude}" +
$"¤t=temperature_2m,relative_humidity_2m,wind_speed_10m,weather_code" +
$"&temperature_unit=fahrenheit" +
$"&wind_speed_unit=mph" +
$"&timezone=auto";Open Models → WeatherData.cs.
Inside the CurrentWeather class, add:
[JsonPropertyName("weather_code")]
public int WeatherCode { get; set; }Your CurrentWeather class should now look like this:
For this activity, you can display the numerical weather code directly.
Open MainPage.xaml.cs.
After the existing weather display code, add:
await DisplayAlert(
"Weather Code",
$"Current weather code: {weather.Current.WeatherCode}",
"OK");Your display section should now look like:
Run the application and select a location. When you click Get Weather, the weather code should appear in a popup.
Instead of displaying the numerical weather code, try changing the application so it displays a description such as:
- Clear
- Partly Cloudy
- Cloudy
- Rain
- Snow
- Thunderstorm
This requires creating a method that converts the numerical weather code into a readable description.
For example you can add this directly under the MainPage class:
private string GetWeatherDescription(int weatherCode)
{
return weatherCode switch
{
0 => "Clear Sky",
1 or 2 or 3 => "Cloudy",
45 or 48 => "Fog",
51 or 53 or 55 => "Drizzle",
61 or 63 or 65 => "Rain",
71 or 73 or 75 => "Snow",
95 => "Thunderstorm",
_ => "Unknown"
};
}Then, inside GetWeatherButton_Clicked, replace your current Weather Code popup:
await DisplayAlert(
"Weather Code",
$"Current weather code: {weather.Current.WeatherCode}",
"OK");with the following code:
string description =
GetWeatherDescription(weather.Current.WeatherCode);
await DisplayAlert(
"Current Weather",
description,
"OK");