Soon, I’m facing a new project where the need for up-to-date currency exchanges is crucial. This is not the first time I’ve done this, but I wanted to make a reusable, self-maintainable class so I don’t have to do it again.

The European Central Bank (ECB) provides the currency exchange rates on a daily basis in XML format, so all there needs to be done, is to wrap the XML file into a generic dictionary for easy use. With that in mind, here are the rules of the Currency class:

  • Use XML file from ECB
  • Update the currencies daily
  • Must still function if the ECB has downtime
  • Must be self maintained
  • Must be plug ‘n play. Only CLR classes can be used.

In order to make the class self maintained it uses a System.Timers.Timer to check the ECB website once an hour for updates. As soon as it finds an update, the XML file is being downloaded and parsed. This is the Download method which runs once an hour.

/// <summary>

/// Downloads the latest exchange rates from ECB.

/// </summary>

private static void Download()

{

  try

  {

    _Timer.Stop();

    HttpWebRequest request = WebRequest.Create(_Url) as HttpWebRequest;

    using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)

    {

      if (response.StatusCode == HttpStatusCode.OK && response.LastModified != _LastModified)

      {

        using (StreamWriter writer = new StreamWriter(_Filename, false))

        {

          StreamReader reader = new StreamReader(response.GetResponseStream());

          writer.Write(reader.ReadToEnd());

          reader.Close();

        }

        _LastModified = response.LastModified;

      }

    }

 

    _Timer.Interval = _UpdateInterval;

  }

  catch (Exception)

  {

    // If an error occurs, try again in 10 minuttes.

    _Timer.Interval = 1000 * 60 * 10;

  }

  finally

  {

    _Timer.Start();

  }
}

Examples of use


double fromUSDtoEUR = Currency.Exchange("USD", "EUR", 12.75 );

double rateFromUSDtoNOK = Currency.GetRate("NOK", "USD");

     

if (Currency.LastUpdated < DateTime.Now.Date)

  Currency.Update();

 

foreach (string currency in Currency.GetAllRates().Keys)

{

  Response.Write(string.Format("{0}: {1}<br />", currency, Currency.GetAllRates()[currency]));
}

Implementation

Download the Currency.cs below and add it to the App_Code folder of your website. Then add the following to the <appSettings> section of the web.config.

<add key="Currency.Filename" value="~/currency.xml"/>

The filename value can either be a relative or absolute file path.

Download

Currency.zip (1,93 KB)

Today, I had to build web form that took user input from standard ASP.NET input controls. In one of the text boxes the user must to enter a valid URL, so I had to make some validation logic. But first of all, I had to find out what kind of URL’s we would accept as being valid. These are the rules we decided upon:

  • The protocol must be http or https
  • Sub domains are allowed
  • Query strings are allowed

Based on those rules, I wrote this regular expression:

(http|https)://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?

It is used in a RegularExpressionValidator control on the web form and on a business object in C#.

<asp:RegularExpressionValidator runat="Server"

  ControlToValidate="txtUrl"

  ValidationExpression="(http|https)://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?"

  ErrorMessage="Please enter a valid URL"

  Display="Dynamic" />

Here is the server-side validator method used by the business object:

using System.Text.RegularExpressions;

 

private bool IsUrlValid(string url)

{

  return Regex.IsMatch(url, @"(http|https)://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?");

}

You can add more protocols to the expression easily. Just add them to the beginning of the regular expression:

(http|https|ftp|gopher)://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?

You can also allow every thinkable protocol containing at least 3 characters by doing this:

([a-zA-Z]{3,})://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?