Modernising a simple legacy .NET site

The first in series of posts where I walk through moving a small ASP.NET MVC 5 app into Azure.
June 02 2020
Azure    Web Api mvc    iRacing

This is about 3 years too late to be a tutorial, so think of it more as a blog of my experience.  I’ve got an existing ASP.NET MVC 5 website hosted on IIS and Windows 10 and I will be modernising it to .NET Core and making use of the services that Azure provides, to get it off being hosted at my home.

Source code for the site I'll be modernising is available on Github, here (in the "original" subfolder").

Once moved to Azure, I'll be adding additional features including expanding it from a charting for limited subset of people, to allowing anyone to create charts for any combination of people.  To do this I'll be brining in new technologies and significantly expanding the system design in order to scale with the expected usage.

Background and overview

Four years ago I was the team leader of the iRacing section of a larger Sim Racing community.  We numbered about 15 iRacers and raced across a few series in iRacing.  iRacing has tables that list all of there about 300,000 members, but I wanted a way to easily show where our small team stood relative to each other, both in iRacing overall, and each series we raced in.

We had threads in our (phpBB) forum for each of the series we raced in on a season by season basis, as well as an overall thread for our iRacing successes.  I wanted to display a table of each of our statistics in the overall thread, and a table on where we stood in each series in the respective threads. 

I wanted each table to be automatically updated and it had to look well-presented within the limitations of what a phpBB forum post allows.  That reduced my options significantly and I decided that the best solution was to provide the tables as images generated by the web site, with the latest available iRacing data. 

The choice of images allowed the data to be easily embedded in posts using the [img] tag, and allowed them to be embedded anywhere on the web, using an <img> html element. The images would potentially be updated with every request to the server for that image.  

On the iRacing forums, members also often had “signatures” at the bottom of each post. These signatures have almost exclusively been generated by, one of the many 3rd party free addons to the sim.  These signatures contained a basic summary of the persons results on the platform, including: their name, their iRating, the Safety Rating and some other configurable statistics.  I wanted to do something similar that included providing a custom look that represented our team.  As with the tables, the signatures needed to be updated as our statistics changed.

Technical considerations and implementation

The overall solution I chose at the time was an ASP.NET MVC app running on .NET Framework 4.6.1.  I exposed action methods for each type of chart and type of signature. 


  • A request to /table/stats should provide the current overall details statistics table.
  • A request to /table/series/{seriesId} should provide a table detailing where we stood relative to each other in a given series.
  • A request to /table/leaderboard should provide a summarised statistics table, including only name, iRating, and Safety Rating.
  • A request to /signature/road/{customerId} should provide a full-sized themed signature for use on the iRacing forums, based on the road racing license.
  • A request to /signature/road/mini/{customerId} should provide a compact themed signature.
  • Other charts and signatures as required (e.g. signatures for oval, oval dirt, road dirt – and time trial leaderboards).
  • The system must connect to iRacing to retrieve the data required to produce the tables and signatures.
  • The data associated with the same request must be dynamic, i.e the tables and signatures must change to reflect the current values in iRacing.


As well as the site outputs, I needed to consider site performance.  There is no iRacing API to connect to and retrieve data, so any connection will simulate what a user can do through their web browser, a technique known as scaping.  Fortunately, iRacing provided CSV downloads to the user, in some screens, but I still had to get to those screens, ensure I was authenticated, and formulate the correct query to get the data I wanted.

Given this, I did not want to be going to iRacing and scraping their site every time a request for an image was made.  That meant caching. 

Given the small scale of the project and that data for every user wasn’t provided in a delta, meaning I’d need to delete all existing data before a re-import, I decided a database was inappropriate for this solution. I determined that downloading the CSV files and persisting to disk was the most appropriate solution (even then, I abstracted that behind a Repository).  I chose to refresh CSV files on a regular basis, but not every call. I think if the files were older than 6 hours I’d re-query iRacing.

Given all images are delivered over HTTP, I could make use of the inbuilt caching.  I chose to use Output Caching on each of the MVC actions.  This meant the users browser would store the image locally, on the client computer, for a duration of time, before requesting the image from the server.  That was my frontline of defence against overloading the server with unnecessary work.

Some of the techniques I chose not to include are:

  • Logging
  • Dependency injection (though I still programmed to interfaces)

Deployment was also extremely simplified.  I would check the entire source code (including packages and binaries) to source control and then perform a git pull on my “production” server (a PC in my lounge room).

Where to from here?

Over the next period of time (I don’t know how long ) I’ll be moving this website to be Azure hosted and making use of the various technologies that come with that Cloud provider.  I also want to significantly increase the scope of the application, adding:

  • Multiple teams can be created
  • All tables are provided in the context of a team.
  • iRacers can be assigned to teams.
  • Signatures can be supplied for each team.

This will almost certainly mean something more sophisticated than stored CSV files will be brought into the solution. 

The next step in the modernisation process will be converting the existing app to be .NET Core and using Azure blob storage for storage of CSV files and base signature images, and moving the app to be hosted on Azure.

Post a comment

comments powered by Disqus