18 Mar
2010

NHibernate, HttpModules, ASP.NET JSON Web Services and Database Transactions

Category:UncategorizedTag: :

First of all sorry for the frankly appalling title which is actually longer than some of my posts. In order to explain let’s start with a problem definition. These are the elements that were in play:

  1. An ASP.NET 3.5 Web Forms based website (although #3 below is really the key factor )
  2. NHibernate
  3. The use of an HttpModule to implement the Open Session in View pattern and provide a Unit of Work implementation (one ISession per HTTP request)
  4. ASP.NET web services returning JSON (might well be a problem if the result was XML as well)

In an “old fashioned” Web Forms scenario everything works perfectly. If some unexpected event occurs during a postback then an Exception is thrown and it bubbles up to the HttpModule which rolls back the transaction.

However with a JSON web service (we’re not using WCF so we just have an System.Web.Services.WebService flagged with a ScriptService attribute) when an unexpected event occurs the magic of the framework catches it and the ScriptMethod simply returns the Exception converted to JSON. This was being correctly handled in our UI but because an Exception is not thrown so the HttpModule thinks that everything is OK and incorrectly commits our transaction. And because processing didn’t necessarily finish and our data could therefore get into an inconsistent state (which is even worse than a plain wrong state).

In order to work around this feature I hooked into the EndRequest event in the HttpModule and check the StatusCode of the Repsonse. Here’s the method that I created:

private bool IsAjaxError()
{
  return HttpContext.Current.Response.StatusCode == 500 && HttpContext.Current.Request.RawUrl.Contains(".asmx");
}

Obviously if an error is detected I can take the appropriate action. So if you’re using the above combination of technologies be careful because what you think is happening and what is happening might be two entirely different things.