Exception Handling for Web API Controller Constructors

The generally-recommended best practice for exception handling within Web API is to to use exception filters.  Once registered, these classes sit in the processing pipeline for a message and can react to exceptions that are thrown by actions.

A Problem

The issue with the statement above is the qualifier “by actions”.  While an exception filter will correctly handle any errors thrown from within an action method, it will be bypassed by exceptions thrown during the creation of the controller.

These exceptions include two categories of error: exceptions thrown from within the controller constructor, and a failure to locate or invoke an appropriate constructor.  The latter problem is, for me, the more common – I use the Autofac MVC & WebAPI integrations (highly recommended, by the way) to handle dependency injection in controllers, and there are quite often scenarios where one of the dependencies is not available.  In these cases I really need a way to catch and to nicely handle those exceptions.

One way in which we can achieve this lofty aim is by creating a custom implementation of IHttpControllerActivator.

The Controller Activator

The IHttpControllerActivator interface only contains one method:

IHttpController Create(
	HttpRequestMessage request,
	HttpControllerDescriptor controllerDescriptor,
	Type controllerType
)

This method is responsible for creating and returning an instance of a specified controller before the API action is invoked.  This is perfect for our scenario because it is a very specific responsibility; we need a custom implementation, but we will not have to worry about how the controller type is selected, how the action is selected or how it is invoked.

Implementing a Decorator

To be honest, we don’t really want to get into how the controller is actually created – we just want to wrap it in a try { … } catch { … } – so instead of creating our own activator we should just write a decorator pattern to wrap the existing implementation.

public class ExceptionHandlingControllerActivator : IHttpControllerActivator
{
	private IHttpControllerActivator _concreteActivator;

	public ExceptionHandlingControllerActivator(IHttpControllerActivator concreteActivator)
	{
		_concreteActivator = concreteActivator;
	}
		
	public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
	{
		try
		{
			return _concreteActivator.Create(request, controllerDescriptor, controllerType);
		}
		catch
		{
			//custom handler logic here
		}
	}
}

This simple class constructs on a concrete instance of IHttpControllerActivator, then calls down to that concrete instance within a try/catch block.  We can then implement our custom exception handling in the catch.

Now all we need to do is replace the default activator with our one.

Hooking It Up

We need to tell Web API to use our new controller activator instead of the default, and (as with so much else in Web API) we do this through the HttpConfiguration object; specifically, the Services property.

This comes with a convenient Replace method that allows us to insert our implementation in place of the default version.  We also want to pass that default into the constructor of our class, so we end up with something like this:

GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator), 
	new ExceptionHandlingControllerActivator(
		GlobalConfiguration.Configuration.Services.GetHttpControllerActivator()
	)
);

It looks a little messy, but it’s not complicated: grab a reference to the current activator, pass it into our decorator, then pass that into the Replace method.

Simple!

About these ads

Using Blob Snapshots to Backup Azure Virtual Machines

Now that Windows Azure Virtual Machines are out of preview it seems like a good time to look at how we can safeguard against the inevitable disasters that will befall those VMs.

Azure Virtual Machines use blob storage for both OS and data disks so we can get some basic backups going with nothing more than the blob API and a simple powershell script.

Setting Up the API

Before we can start writing anything to make use of the blob API we need to make sure that we have it downloaded and configured. How, you ask?

  • Firstly, install Windows Azure Powershell from here or through the Web Platform Installer
  • Next, create a new powershell script and import the API namespace
    Add-Type -Path "C:\Program Files\Microsoft SDKs\Windows Azure\.NET SDK\2012-10\bin\Microsoft.WindowsAzure.StorageClient.dll"
    

Setting Up Your Subscription

You will also need to configure powershell to use your Windows Azure account. Here’s how (as described by the excellent Michael Washam):

  • Download your Azure publish profile through the portal or with this link
  • Import the downloaded settings file using the Import-AzurePublishSettingsFile cmdlet
    Import-AzurePublishSettingsFile "c:\downloads\subscription.publishsettings"
    
  • Finally, set your subscription as active
    Set-AzureSubscription -SubscriptionName "[subscription name]"
    

At this point you are able to start using the API with your Azure account.

The CloudBlob Class

Most of the operations we want to invoke for our backup are going to be called on the CloudBlob class, which represents both the original blob and any snapshots that are acquired from Azure.

Finding the Right Blob

The first thing that we need to do is get a reference to the blob that contains the virtual hard disk (vhd) for our virtual machine, and to do that we need to dig through the portal.

Browse to the Dashboard for your virtual machine and you will see something like:

2013-04-24 18_10_25-Virtual machines - Windows Azure

Make a note of the disk name (highlighted) then browse to Virtual Machines > Disks. This will display a table listing all the disks that are being used by virtual machines, to which VMs they are attached and their location. From the table, locate the disk with the matching name and grab the location URL, which will look something like this:

http://storageaccountname.blob.core.windows.net/vhds/diskblobname.vhd

Make a note of both the storage account and disk blob names, and we have enough information to identify the correct blob.

Getting a Blob Reference

We now need to grab an instance of CloudBlob that represents our VM disk. We do this using the CloudBlobClient.GetBlobReference method, building up the required credentials from the storage account details.

$storageAccount = "[storage account name]"
$blobPath = "vhds/[disk blob name.vhd]"

#get the storage account key
$key = (Get-AzureStorageKey -StorageAccountName $storageAccount).Primary

#generate credentials based on the key
$creds = New-Object Microsoft.WindowsAzure.StorageCredentialsAccountAndKey($storageAccount,$key)

#create an instance of the CloudBlobClient class
$blobClient = New-Object Microsoft.WindowsAzure.StorageClient.CloudBlobClient($blobUri, $creds)

#and grab a reference to our target blob
$blob = $blobClient.GetBlobReference($blobPath)

We now have a $blob variable that we can start using to manipulate the blob.

Creating Snapshots

Creating a new snapshot is an incredibly simple step – we can just call CreateSnapshot!

$snapshot = $blob.CreateSnapshot()

The $snapshot variable now contains another instance of CloudBlob that represents the snapshot, and we can use this to download the snapshot content at any point in the future.

That’s useful, but it’s not that useful as we’re unlikely to keep a reference to that object until the next time we need it. So how do we find snapshots that have been made in the past?

Finding Snapshots

The API includes a method on the CloudBlobContainer class that will list all blobs within a particular container (in this case, vhds). Unfortunately it does not do much in the way of filtering, so we need to add some code of our own.

#assume we can get our blob as before
$blob = Get-Blob

#we need to create an options object to pass to
#the ListBlobs method so that it includes snapshots
$options = New-Object Microsoft.WindowsAzure.StorageClient.BlobRequestOptions
$options.BlobListingDetails = "Snapshots"
$options.UseFlatBlobListing = $true
$snapshots = $blob.Container.ListBlobs($options);

#once we have the results we need to manually filter 
#the ones we aren't interested in just now
foreach ($snapshot in $snapshots)
{
	#make sure that the blob URI ends in our blobPath variable from earlier
	if ($snapshot.Uri -notmatch ".+$blobPath$") { continue }

	#and make sure that the SnapshotTime is set - this filters out
	#the current live version of the blob
	if ($snapshot.SnapshotTime -eq $null) { continue }

	Write-Output $snapshot
}

If we wrap this up in a Get-Snapshots function then it will return each snapshot of our blob in date order.

Now that we can get a list of snapshots associated with a blob, we want to be able restore the “live” blob to a point in the past.

Restoring the Blob

Once we have a reference to both the current blob and the snapshot that we want to restore, it’s trivial to overwrite the current blob with the older version:

#grab the snapshots for the blob as described above
$allSnaphots = Get-Snapshots

#restore to original version
$blob.CopyFromBlob($allSnapshots[0])

#restore to most recent snapshot
$blob.CopyFromBlob($allSnapshots[$allSnapshots.Length-1])

We probably want to be a little bit more careful with this though, as you could inadvertently overwrite the current version and lose our data. To avoid this we can take another snapshot as a backup prior to restoring – this way we are in no risk of losing any data.

#grab the snapshots for the blob as described above
$allSnaphots = Get-Snapshots

#take a backup snapshot before restoring
$backupSnapshot = $blob.CreateSnapshot()

#and then restore safely
$blob.CopyFromBlob($allSnapshots[$allSnapshots.Length-1])

One important thing to note about this approach: it simply restores the disk. Understandably, Azure gets touchy about you overwriting the disk of a live machine, so you will have to make sure that the VM is shut down and disassociated with the disk before you can restore.

Obviously this is not a complete backup solution but it can quickly give you a means to recover your Azure virtual machines to an earlier point. Everything is in powershell so can be easily scheduled to run automatically at scheduled intervals, and the snapshots are fully accessible so a more in-depth backup process can pull them to another location as required.

Translating Date Formats in JavaScript

Urgh, dates.  It’s always bloody dates.  Whether it’s different time zones, localised formats (both long and short) or any one of a hundred other annoying little problems…somehow, whenever you start working with dates, everything goes to hell.

We can all agree on how we should be dealing with dates, right?  ISO 8601 for everything in the backend (transport & database), then a localised format to present to the user in the UI layer. As Randall Munroe recently said/drew:

Date Formats

That’s all well and good, but when your UI layer makes use of JavaScript you have the additional headache of dealing with the JavaScript Date object (though you can avoid real agony by using momentjs).

The Most Important Piece of (Off-Topic) Advice in this Post

If you are not already using momentjs for every date-related scenario then you are almost certainly wasting a lot of time.  It’s under 6kb, it will do more-or-less everything you want with dates…go get it now.

The problem with dates in JavaScript gets even worse if you are pulling your date format from somewhere other than the client.  Suppose that you have a “preferred date format” setting for each user on the server – you need to somehow pass that into your JavaScript.

Admittedly momentjs makes this easier: you can parse the dates from the server using ISO format and then display them in whatever crazy format you want.

var dateFromServerInIsoFormat = "2013-01-14",
    preferredFormatFromServer = "D * MMM * YYYY",
    parsed                    = moment(dateFromServerInIsoFormat, "YYYY-MM-DD"),
    formatted                 = parsed.format(preferredFormatFromServer);

console.log(formatted);
// -> 14 * Jan * 2013

This works – it will allow us to format dates within our JavaScript using a date format specified by the server – but it relies on an incorrect assumption: that the server and momentjs share a date format language.

One Format, Many Format Definitions

Perhaps the best way to demonstrate this problem is with an example.  Let’s assume that we are running ASP.NET on our server, using momentjs to handle dates within our JavaScript, and (just to spice things up) we have a couple of third party JavaScript components: jQuery UI DatepickerjqPlot.

We have a user setting stored on the server that defines our “preferred date format” as…

January 15, 2013

Let’s take a look at how we would define that for our four components.

.NET MMMM d, yyyy Nice and simple so far
momentjs MMMM D, YYYY Slightly different, but still pretty close
jQuery UI Datepicker MM d, yy Ok, getting a little bit trickier…
jqPlot %B %#d, %Y Wait, what?!

What’s going on here?!  You can just about see how you could convert from the .NET format to momentjs, or even to the jQuery UI one without too much pain, but jqPlot is just a mess!

Translating Between Formats

After being plagued by numerous variations on this problem on a recent project, I decided to deal with it properly by creating something to translate between (theoretically) any 2 formats.

The dateFormat object contains definitions for the different format languages, and the convert function translates between them:

var formatFromServer = "MMMM d, yyyy",
    momentFormat = dateFormat.convert(formatFromServer,
                                      dateFormat.dotnet,
                                      dateFormat.moment),
    jqPlotFormat = dateFormat.convert(formatFromServer,
                                      dateFormat.dotnet,
                                      dateFormat.jqplot);

console.log("moment: " + momentFormat);
// -> moment: MMMM D, YYYY

console.log("jqPlot: " + jqPlotFormat);
// -> jqPlot: %B %#d, %Y

Each language definition contains a list of mappings from named tokens (e.g. day-of-week) to their representation in the format:

dateFormat.dotnet = {
    "day-of-month-1": "d",
    "day-of-month-2": "dd",
    "day-of-week-abbr": "ddd",
    "day-of-week": "dddd"
    //...
};

This allows the convert function to create a mapping from one language to another, then use regular expressions to locate and replace matching tokens in the source string.

The source code is available on GitHub along with the tests and some distributables.  At the moment the library only supports 3 formats (.NET, momentjs and jqplot) as these were the 3 I needed most recently, but that list will expand over time – hopefully with some help from the community.

This jsFiddle has a running example of the conversion so feel free to play around, or grab the source yourself from one of the links below.

That’s one fewer headache when you next find yourself stuck working with dates!

Fallback Images with Knockout

After a busy few weeks at work I’ve finally managed to spend some time on knockout development again, and today I found a nice solution to a problem with data-bound images.

In my example I had a list of contacts that were being displayed on the page, and each contact had a URL linking to their profile image.

{
	Id: 1,
	FirstName: "Steve",
	LastName: "Greatrex",
	ProfileImage: "/some/image.jpg"
}

The binding to display the image is initially pretty simple – I can use the attr binding to set the src property on the img element using the vanilla knockout library.

<img data-bind="attr: { src: ProfileImage }" />

Simple enough, right?

Complications

Unfortunately some of my contacts don’t have a ProfileImage property.  Even worse, some of them do have a ProfileImage but it points to a non-existant image.

If I use the attr binding as above then I get an unpleasant looking “missing image” icon…

image

…when what I really want to do is use a placeholder image instead.

The img binding

To resolve this problem I created a new custom binding named img.  This expects a parameter containing an observable src property for the image URL, and either a hard-coded or an observable fallback URL to be used in case of null URLs or errors.

<img data-bind="img: { src: ProfileImage, fallback: '/images/generic-profile.png' }" />

The binding itself is nothing complicated.  As with all custom bindings you can optionally specify an update and an init handler that are called when the value changes and when the binding is initialised respectively.

For this binding, the update handler needs to check the value of both the src and fallback properties, then set the src attribute on the img to whichever value is appropriate.

The only thing that the init function needs to handle is the scenario where the image fails to load (using jQuery.error).

ko.bindingHandlers.img = {
    update: function (element, valueAccessor) {
        //grab the value of the parameters, making sure to unwrap anything that could be observable
        var value    = ko.utils.unwrapObservable(valueAccessor()),
            src      = ko.utils.unwrapObservable(value.src),
            fallback = ko.utils.unwrapObservable(value.fallback),
            $element = $(element);

        //now set the src attribute to either the bound or the fallback value
        if (src) {
            $element.attr("src", src);
        } else {
            $element.attr("src", fallback);
        }
    },
    init: function (element, valueAccessor) {
        var $element = $(element);

        //hook up error handling that will unwrap and set the fallback value
        $element.error(function () {
            var value = ko.utils.unwrapObservable(valueAccessor()),
                fallback = ko.utils.unwrapObservable(value.fallback);

            $element.attr("src", fallback);
        });
    },
};

That’s all there is to it – you can now specify a “primary” and a “fallback” binding for your images to get something like the effect below:

image

Another problem solved by the Swiss army knife that is knockout custom bindings.

Explicitly Controlling Cache Dependencies in MVC

In the past, I have always used the OutputCacheAttribute  when I wanted to cache the result of an Action in my MVC application; it’s simple, and it gets basic caching up and running with very little effort.

Unfortunately “simple and quick” are not quite as useful when you need a little more control…

Scenario

Let’s say you have a resource that you automatically generate in your controller, but that creating that resource takes a long time…

public async Task<ActionResult> Slow()
{
	var resource = await _service.GenerateResource();
	// ...5 minutes later...
	return View(resource);
}

Understandably, you want to cache the result of this action so that subsequent visitors don’t all have to wait around for the resource to be created.  [OutputCache] to the rescue, right?

Not So Fast!

Unfortuantely, the resource is not entirely constant – it can be altered by certain user actions in other areas of the application, and when that happens it will need to be regenerated.

[OutputCache] will allow us to vary the cached result by a number of variables (host, action arguments, custom strings…) and supports timeouts etc, but it does not allow another piece of code somewhere in the application to say “that resource is not longer valid”.

An Alternative to [OutputCache]

One alternative means of caching the results of an action is to call the AddCacheDependency method on the Response object:

public async Task<ActionResult> Index()
{
	Response.AddCacheDependency(new CacheDependency(...));
			
	//...
}

The CacheDependency instance in this example is an ASP.NET class that is used by the caching framework to determine when the resource we created has been changed.

The base CacheDependency implementation allows you to specify one or more file system paths that will be monitored, and will invalidate itself when any of those files is updated.  There is also a SqlCacheDependency class that observes the results of a SQL query and invalidates when they change.

Neither of these implementations will give us quite what we are looking for -  the ability to invoke a method from anywhere within the codebase that explicitly marks the cached content as changed – but they are leading us in the right direction.

If we can create a CacheDependency instance that is uniquely identifiable for the slow resource then we can add it to the response and force it to invalidate itself at a later date.

Extending CacheDependency

Before we can get into how we add our CacheDependency instance, we need to create an implementation that will allow us to explicitly invalidate it through code.  Thankfully, CacheDependency exposes a number of methods to it’s inheriting classes that mean we can achieve our explicit invalidate very easily.

The minimum that we need to do to make the CacheDependency work is to pass a list of paths into the base constructor and to provide a valid value from the GetUniqueID method.  We know that we do not want to depend on any file system resources so we can just pass an empty list into the constructor, and as we need a unique ID anyway (to identify the cached resource later) we can just pass this into the constructor.

class ExplicitCacheDependency : CacheDependency
{
	private string _uniqueId;

	public ExplicitCacheDependency(string uniqueId)
		: base(new string[0]) //no file system dependencies
	{
		_uniqueId = uniqueId;
	}
		
	public override string GetUniqueID()
	{
		return _uniqueId;
	}
}

CacheDependency has a protected NotifyDependencyChanged method that will notify the caching framework that the cached item is no longer valid. In most implementations this would be invoked in some callback, but for our purposes we can just add a new Invalidate method and invoke it directly:

public void Invalidate()
{
	base.NotifyDependencyChanged(this, EventArgs.Empty);
}

Voila – a cache dependency that we can explicitly invalidate.  But how can we get a reference to this in the various places that we need it?

CacheDependencyManager

Creating a new cache dependency doesn’t help us much if we can’t get a reference to it later – otherwise, how can we call Invalidate?  Let’s create a new class that handles the creation and invalidation of the new cache dependencies: CacheDependencyManager.

class CacheDependencyManager
{
	private Dictionary<string, ExplicitCacheDependency> _dependencies
		= new Dictionary<string, ExplicitCacheDependency>();

	public CacheDependency GetCacheDependency(string key)
	{
		if (!_dependencies.ContainsKey(key))
			_dependencies.Add(key, new ExplicitCacheDependency(key));

		return _dependencies[key];
	}

	public void InvalidateDependency(string key)
	{
		if (_dependencies.ContainsKey(key))
		{
			var dependency = _dependencies[key];
			dependency.Invalidate();
			dependency.Dispose();
			_dependencies.Remove(key);
		}
	}
}

Note: in the interests of brevity I have not included the thread-safe version here; this is a terrible idea in the real world, so make sure you include some appropriate locking!

This CacheDependencyManager is intended to hide the detail of how the dependency instances are created and invalidated from calling classes, which it achieves through 2 public methods:

  • GetCacheDependency that creates a new ExplicitCacheDependency if none exists for the specified key, or returns the cached one if it has been previously created
  • InvalidateDependency that attempts to locate an existing cache dependency for the specified key, and invalidates and removes it if one is found.  If one doesn’t exist then it does nothing, so callers don’t need to know whether or not the resource has already been cached

One quick singleton pattern later and we can call these methods from throughout our codebase. When we invoke our slow action for the first time we need to add the dependency to the response using a unique key to identify the slow resource:

Response.AddCacheDependency(
		CacheDependencyManager.Instance.GetCacheDependency("ResourceKey"));

And how do we invalidate the resource after some arbitrary user action? We can just pass that same key into the Invalidate:

public class SomeOtherController : Controller
{
	public ActionResult SomeRandomUserAction()
	{
		CacheDependencyManager.Instance.Invalidate("ResourceKey")
		//...
	}
}

Obviously you could (should!) use dependency injection to pass the CacheDependencyManager to your controllers instead of accessing it directly, but the singleton will suffice for this example.

That’s All Folks

That’s the lot – now we can manually invalidate our slow resource whenever and from wherever we want, and our users can enjoy speedy cached resources the rest of the time!