Inspiration Behind the Article
This article builds upon my previous guide on developing cross-platform apps with .NET MAUI Blazor Hybrid. If you’re new to .NET MAUI or Blazor Hybrid, I highly recommend reading that guide first to grasp the foundational concepts and set up your development environment.
In this article, we’ll focus on creating a real-time currency converter app, an excellent practical use case for cross-platform applications. You’ll learn how to design and develop an app that not only fetches live exchange rates but also delivers a consistent user experience across mobile, web, and desktop platforms, all while leveraging a single UI framework: Blazor.
Here’s a preview of the app running on all three platforms web, mobile, and desktop.
Image 1. Currency Converter on Desktop, Web, and Mobile
SRS for Currency Converter UI
- Currency Selection: A dropdown menu with INR set as the default currency.
- User Input: A numeric input field for entering the number of units.
- Convert Button: Triggers conversion based on the user input and exchange rates.
- Exchange Rates Table: Displays the currency, exchange rate, and converted amount.
- Loading Indicator: Appears while fetching exchange rates.
- UI Requirements: Left-aligned, responsive, and consistent design across platforms.
- Performance: Ensures efficient updates without unnecessary API calls.
Before we start building the currency converter app, it’s essential to understand how to create a Blazor Hybrid app. I covered this in my previous article, [Building Cross-Platform Apps with .NET MAUI Blazor Hybrid], so I recommend reviewing it to get started.
For this project, I have named the app ForExFlow. After creating the solution, you will have the following three projects.
- ForExFlow: The platform-specific project for Desktop and Mobile.
- ForExFlow.Shared: The shared project contains UI components and business logic.
- ForExFlow.Web: The web-specific project for running the Blazor Web app.
Image 2: Solution Explorer - Project Name: ForExFlow
The Service
Create a new folder named "Services" in the "ForExFlow.Shared" project and add the following interface, IForexRateService, and the class, ForexRateService.
IForexRateService: Service interface
Let's start with the service interface. It's quite simple; all we need is a single method that takes a currency as input and returns a dictionary containing country names and their respective exchange rates.
public interface IForexRateService
{
Task<Dictionary<string, decimal>> GetExchangeRatesAsync(string inputCurrency);
}
Code Snippet 1. Service Interface - IForexRateService.
ForexRateService Class: Fetching Exchange Rates via API
The ForexRateService class is an implementation of the IForexRateService interface, we need this class to fetch the live exchange rates from an API (https://api.exchangerate-api.com/v4/latest).
1. Private Field
2. Constructor
3. GetExchangeRatesAsync
- This async method takes a base currency (e.g., "USD", "EUR") and retrieves exchange rates relative to it. Returns a Dictionary<string, decimal>, mapping currency codes (like "INR", "GBP") to their exchange rates.
- Appends the baseCurrency to the base API URL (e.g., "https://api.exchangerate-api.com/v4/latest/USD").
- Creates a RestRequest using RestSharp and sends a GET request asynchronously.
- Uses System.Text.Json to deserialize the API response into a C# object (ExchangeRateResponse - code snippet 5).
public async Task<Dictionary<string, decimal>> GetExchangeRatesAsync(string baseCurrency)
{
var url = $"{baseCurrency}";
var request = new RestRequest(url, Method.Get);
var response = await _client.ExecuteAsync(request);
if (!response.IsSuccessful)
{
throw new Exception($"Failed to fetch exchange rates");
}
var options = new JsonSerializerOptions
{
DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
var data = JsonSerializer.Deserialize<ExchangeRateResponse>(response.Content, options);
if (data == null || data.Rates == null)
{
throw new Exception("No exchange rates found in the response.");
}
return data.Rates;
}
Code Snippet 4. GetExchangeRatesAsync: Fetching Exchange Rates from API.
4. ExchangeRateResponse: Mapping API Response.
- This class represents the structure of the API response.
- The most important field is Rates, a dictionary storing currency rates.
private class ExchangeRateResponse
{
public string Base { get; set; }
public string Date { get; set; }
public Dictionary<string, decimal> Rates { get; set; }
public string Provider { get; set; }
public string WarningUpgradeToV6 { get; set; }
public string Terms { get; set; }
public int TimeLastUpdated { get; set; }
}
Code Snippet 5. class ExchangeRateResponse.
The UI: ForexComponent.razor
Create a new component "ForexComponent.razor" under the pages folder in the "ForExFlow.Shared" project.
1. Currency Selection Dropdown
2. User Input for Units
3. Exchange Rates Table
Code-Behind Logic: ForexComponent.razor.cs
1. Dependency Injection: Injecting the Forex Service
2. Variables
- ExchangeRates: Stores exchange rates retrieved from the API.
- BaseCurrency: Tracks the currently selected base currency (default: "USD").
- Currencies: A list of available currencies.
- userInput: Stores the user’s input value for conversion (default: 1).
private Dictionary<string, decimal> ExchangeRates;
private string BaseCurrency = "USD";
private List<string> Currencies = new List<string> { "USD", "EUR", "GBP", "JPY", "AUD" };
private decimal userInput = 1;
Code Snippet 10. Variables.
3. Methods
Mobile and Desktop app
This is the beauty of this architecture; we are done with the core code. Now, we just need to reference the code.
This will ensure that the ForexRateService is available to be injected into components throughout the mobile and desktop app. Once the service is registered, the app is ready to fetch and display exchange rates across both platforms.
Image 3. Mobile app: Currency Converter
Image 4. Desktop app: Currency Converter
Web app
To achieve the same functionality in the web app, expand the ForExFlow.Web project and open the Program.cs file. Add the same line of code to register the Forex service as we did for the mobile and desktop apps. This ensures that the web application also has access to the exchange rate service.
Image 5. Webapp: Currency Converter
Conclusion
In this article, we built a cross-platform currency converter using the MAUI Blazor Hybrid Web App, which allows it to run on the web, desktop, and mobile. We implemented a service to fetch real-time exchange rates.
By leveraging Blazor’s component-based architecture and .NET MAUI’s cross-platform capabilities, we could develop a unified codebase for multiple platforms.