Search

Currency Converter Server with C#

0 views

Building a Dynamic Currency Converter Server

When you build a web‑based currency converter, the most common approach is to embed a fixed list of rates into the application. Those rates are typically read from a local XML file that you update manually or on a regular schedule. The downside is that if you need the freshest data or if you want to keep the converter lightweight, you have to write a routine that fetches the rates from an external source, parses them, and writes a new XML file that the application can consume. In this guide we walk through that whole process, from the web scraper that pulls the rates from a public exchange‑rate service to the C# DLL that packages the data and finally the ASP.NET Web Forms page that performs the conversion.

The data source we use is the PACIFIC Exchange Rate Service, which publishes daily rates for more than 240 currencies. The website presents the rates in an HTML table; our scraper will extract the table rows using regular expressions, then produce a clean Rates.xml file. Because the XML is the only thing the Web Forms page needs, the rest of the application stays simple and maintainable. We also provide a command‑line executable that can be scheduled in Windows Task Scheduler to run every evening, ensuring that the converter always shows the latest rates without manual intervention.

Below you’ll find the key components: a DLL that performs the extraction and conversion logic, a small executable that drives the DLL and writes the XML, and an ASP.NET Web Forms page that loads the XML and performs the user‑initiated conversion. Each piece is written in plain C# 7.0, uses the .NET Framework’s standard libraries, and can be compiled with the same command script that ships with the source.

By the end of this walkthrough you’ll have a ready‑to‑deploy currency converter that updates itself automatically, an XML format that can be extended or replaced, and an ASP.NET page that demonstrates how to bind data to controls, sort it, and display results in a user‑friendly way. You can then take this foundation and plug in additional features, such as a history log, different base currencies, or an API endpoint for other services to consume the rates.

Creating the CurrencyConverter.dll Component

The first step is to write a small library that can be called from both the console program and the ASP.NET page. The library’s public surface is intentionally narrow: it accepts a URL that points to an HTML page, downloads the content, extracts the rows that contain currency names and rates, and returns a collection of Rate objects. The Rate class is a lightweight DTO with two properties, Currency and Exchange

To keep the extraction logic fast and easy to maintain, we use a single regular expression that matches all <td> elements inside the table. The pattern <td.?>(.?)</td> captures the inner text of each cell while ignoring any attributes. Because the table has a predictable number of cells per row (currency name, full name, and the exchange rate), we can iterate over the matches in groups of three, creating a new Rate each time.

Below is the core of the CurrencyConverter class. Notice how we avoid any third‑party libraries; the entire implementation relies on System.Net.Http for downloading and System.Text.RegularExpressions for parsing.

Prompt
public class CurrencyConverter</p> <p>{</p> <p> private readonly HttpClient _client = new HttpClient();</p> <p> public List<Rate> ExtractRates(string url)</p> <p> {</p> <p> var html = _client.GetStringAsync(url).Result;</p> <p> var regex = new Regex(@"<td.<em>?>(.</em>?)</td>", RegexOptions.IgnoreCase | RegexOptions.Singleline);</p> <p> var matches = regex.Matches(html);</p> <p> var rates = new List<Rate>();</p> <p> for (int i = 0; i + 2 < matches.Count; i += 3)</p> <p> {</p> <p> var currency = matches[i].Groups[1].Value.Trim();</p> <p> var name = matches[i + 1].Groups[1].Value.Trim(); // unused but available if needed</p> <p> var exchangeStr = matches[i + 2].Groups[1].Value.Trim();</p> <p> if (decimal.TryParse(exchangeStr, NumberStyles.Any, CultureInfo.InvariantCulture, out decimal exchange))</p> <p> {</p> <p> rates.Add(new Rate { Currency = currency, Exchange = exchange });</p> <p> }</p> <p> }</p> <p> return rates;</p> <p> }</p> <p>}</p> <p>public class Rate</p> <p>{</p> <p> public string Currency { get; set; }</p> <p> public decimal Exchange { get; set; }</p> <p>}</p>

Because the library is compiled into a DLL, the consuming code can reference it without pulling in unnecessary dependencies. The console program below demonstrates how to call ExtractRates, then pass the result to an XML writer that will generate Rates.xml

Generating the Rates.xml File on the Fly

The XML format that the Web Forms page consumes is deliberately simple: a root element <Rates> containing a list of <Rate> nodes, each holding a <Currency> and an <Exchange> element. The XmlTextWriter class from System.Xml makes it straightforward to write well‑formatted XML.

The console application BuildXML stitches the two pieces together. First it constructs a CurrencyConverter instance, then it calls ExtractRates with the PACIFIC URL. Once the list of rates is in memory, we open an XmlTextWriter, write the start document, add the root node, iterate over the rates, and close the writer. The resulting Rates.xml file contains all 242 entries sorted exactly as they appear on the source page, which is why we later sort them in the ASP.NET page.

Prompt
class BuildXML</p> <p>{</p> <p> static void Main()</p> <p> {</p> <p> var url = "http://pacific.commerce.ubc.ca/xr/rates.html";</p> <p> var converter = new CurrencyConverter();</p> <p> var rates = converter.ExtractRates(url);</p> <p> var xmlPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Rates.xml");</p> <p> using (var writer = new XmlTextWriter(xmlPath, Encoding.UTF8))</p> <p> {</p> <p> writer.Formatting = Formatting.Indented;</p> <p> writer.WriteStartDocument();</p> <p> writer.WriteStartElement("Rates");</p> <p> foreach (var rate in rates)</p> <p> {</p> <p> writer.WriteStartElement("Rate");</p> <p> writer.WriteElementString("Currency", rate.Currency);</p> <p> writer.WriteElementString("Exchange", rate.Exchange.ToString(CultureInfo.InvariantCulture));</p> <p> writer.WriteEndElement(); // Rate</p> <p> }</p> <p> writer.WriteEndElement(); // Rates</p> <p> writer.WriteEndDocument();</p> <p> }</p> <p> }</p> <p>}</p>

Running BuildXML.exe from the command line updates Rates.xml instantly. The compile.bat script bundled with the source compiles CurrencyConverter.cs and BuildXML.cs into the DLL and the console executable. Scheduling this script to run nightly keeps the converter data fresh without any manual clicks.

Integrating the XML with an ASP.NET Web Form

The final piece is the Web Forms page that shows the converter to users. The page’s code‑behind does two main things: it loads Rates.xml into a DataSet, sorts the table by currency name, and binds the result to a ListBox. When the user selects a currency and enters an amount, the button click handler looks up the selected currency’s exchange rate, multiplies it by the amount, and displays the result in a Label

Because the XML file is small and the dataset is held entirely in memory, the page performs the lookup quickly. The use of a DataView to sort the rates demonstrates a clean separation between data retrieval and presentation logic.

Prompt
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Converter.aspx.cs" Inherits="CurrencyConverter.Web.Converter" %></p> <p><%@ Import Namespace="System.Data" %></p> <p><%@ Import Namespace="System.Globalization" %></p> <p><%@ Import Namespace="System.IO" %></p> <p><html></p> <p><body></p> <p><form id="form1" runat="server"></p> <p> <asp:ListBox ID="lstboxCurrency" runat="server" Width="200px"></asp:ListBox></p> <p> <br /></p> <p> Amount: <asp:TextBox ID="Amount" runat="server" Width="100px"></asp:TextBox></p> <p> <br /></p> <p> <asp:Button ID="btnConvert" runat="server" Text="Convert" onclick="btnConvert_Click" /></p> <p> <br /></p> <p> Result: <asp:Label ID="Result" runat="server" Text="" /></p> <p></form></p> <p></body></p> <p></html></p>

The code‑behind file is the heart of the conversion logic. The Page_Load method checks IsPostBack; on the first load it pulls the XML, creates a DataView sorted by currency, and binds the view to the list box. The btnConvert_Click method fetches the selected currency from the list box, retrieves the corresponding exchange rate, and calculates the amount. A small try/catch block handles format errors so the page never crashes if the user enters a non‑numeric value.

Prompt
public partial class Converter : System.Web.UI.Page</p> <p>{</p> <p> protected void Page_Load(object sender, EventArgs e)</p> <p> {</p> <p> if (!IsPostBack)</p> <p> {</p> <p> var ds = new DataSet();</p> <p> ds.ReadXml(Server.MapPath("Rates.xml"));</p> <p> var dv = ds.Tables[0].DefaultView;</p> <p> dv.Sort = "Currency ASC";</p> <p> lstboxCurrency.DataSource = dv;</p> <p> lstboxCurrency.DataTextField = "Currency";</p> <p> lstboxCurrency.DataBind();</p> <p> }</p> <p> }</p> <p> protected void btnConvert_Click(object sender, EventArgs e)</p> <p> {</p> <p> try</p> <p> {</p> <p> var rows = ds.Tables[0].Select($"Currency = '{lstboxCurrency.SelectedItem.Text}'");</p> <p> if (rows.Length == 0)</p> <p> return;</p> <p> var amount = Convert.ToDecimal(Amount.Text, CultureInfo.InvariantCulture);</p> <p> var rate = Convert.ToDecimal(rows[0]["Exchange"], CultureInfo.InvariantCulture);</p> <p> var result = amount * rate;</p> <p> Result.Text = result.ToString("F2", CultureInfo.InvariantCulture);</p> <p> }</p> <p> catch</p> <p> {</p> <p> Result.Text = "Error";</p> <p> }</p> <p> }</p> <p>}</p>

Deploying the compiled DLL, the console executable, and the ASP.NET files to a web server creates a fully functional currency converter. Users can pick any of the 242 currencies, enter an amount, and get an instant conversion based on the latest rates pulled from the PACIFIC service. The whole system remains small and straightforward to extend; for example, you could replace the HTML scraper with a REST API call, add caching to reduce load on the external site, or even expose the XML as a public endpoint for other applications.

Suggest a Correction

Found an error or have a suggestion? Let us know and we'll review it.

Share this article

Comments (0)

Please sign in to leave a comment.

No comments yet. Be the first to comment!

Related Articles