A better app_offline.htm for ASP.Net

As we know, the presence of an app_offline.htm in an ASP.Net site will take the site down for maintenance or update, displaying whatever is in the file, e.g. an image, and some informative blurb. As ScottGu says, make sure the file is larger that 512 bytes to avoid the IE6 “friendly errors” feature.

Whilst it’s a convenient way to bring down a site, it brings it down a bit harshly, shutting down the App Domain and all sessions, which is really nice if your visitors are half-way through a financial transaction. I wanted a way to keep active users in their session, send new visitors to the site offline page and track how many people are still connected to the site.

My solution is two-fold: a simple HttpModule and a PerfMon graph. First, the HttpModule:

  1. Create a new class, calling it SiteUnavailable and make sure it inherits from IHttpModule.
  2. Use the smart tag to implement the IHttpModule members, which should give you Init and Dispose.
  3. In the Init, add the following:
    context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
  4. Add the following method:
    void context_PreRequestHandlerExecute(object sender, EventArgs e)
    {
    HttpApplication app = (HttpApplication)sender;
    HttpContext context = app.Context;
    if (System.IO.File.Exists(context.Server.MapPath("~/site_unavailable.htm")) && context.Session.IsNewSession)
    {
    context.Response.Redirect("~/site_unavailable.htm");
    }
    }
  5. In the Dispose method, remove the NotImplementedException and replace with a pithy comment of your choice ;)
  6. Add the following line to your web.config file in the httpModules section:
    <add name="SiteUnavailable" type="YourNamespace.SiteUnavailable"/>

That’s it – just create a file called site_unavailable.htm in the site root, filling it with an informative text, a logo, etc., and make sure it’s over 512 bytes. Now, when a vistor comes to the site and that page exists, they’ll be redirecetd to it. If you create / rename the file when users are active, they’ll still get to use the site until they end their session and try to visit the site again.

How’s it work? Well, the code speaks for itself: it checks for the site unavailable file and whether the session is a new one. If it is, then the user is redirected. The PreRequestExecuteHandler event is used because the Session object is available at that point, but main processing hasn’t really started yet. Yes, it’s looking for a hard-coded filename, but that’s what you’ve got with app_offline.htm as well.

That’s half the problem solved, now how do we see how many users are connected to the site? Enter Perfmon…

  1. Run Perfmon, and then right-click the graph and select Add Counters…
  2. For the Performance object, select Web Service
  3. Select the Current Connections counter, and then select your website from the “Select instances from list”, er, list
  4. Click Add, and then marvel at the metrics as they show the number of users connected to your site.

Now, when you enable the siteunavailable.htm page, you can watch the perfmon website connection counter go down as users finish their sessions. When it gets to zero, you can go ahead with your update, then rename the siteunavailable.htm page (to _siteunavailable.htm, for example) and hey presto, your site’s back and updated.

As an aside, it may help the perfmon connection counter reach zero quicker if the content of your siteunavailable.htm page says something like “please close this page to enable us to complete the upgrade quicker”, and it would be helpful to provide an estimated time of completion.

Thoughts? Comments?

About mike

A nice guy, web developer using ASP.Net, martial arts fan and practitioner (when not crippled), film buff, husband and father :-)