Taking an ASP.NET 2.0 Application Offline
By Scott Mitchell
Introduction
In a perfect world, once a web application has been deployed and is live on the Internet or intranet, it will never experience
any downtime. However, this is not very realistic in the real world because most applications grow and change and get updated
over time. For example, as users interface with the application they may unearth bugs, or they may provide suggestions for
new features or ways to enhance the user experience. After squashing those bugs and implementing the requested enhancements,
the updated code base needs to be deployed to the production environment. This may involve updating ASP.NET pages, configuration
files, making database modifications, and so on.
When updating a web application that's currently in production, it is best to take the application offline so that users
understand that the application is being worked on. This can be accomplished in a variety of ways, from simply stopping the
web server software to displaying a web page that informs the user that the site is offline for maintenance.
What you don't want to do is have the application appear to work, only to have some error pop up later because you are in
the middle of updating the production server. This is a sure-fired way to frustrate your users.
In this article we will discuss options for taking a web application offline. Read on to learn more!
Taking a Website Offline through IIS
If you are hosting a production website, chances are your site is being served using Microsoft's
Internet Information Services (IIS) web server software. IIS is Microsoft's professional-grade
web server software and powers virtually all ASP.NET applications. The most encompassing way to take a website offline
is through IIS. (Note: in shared, hosted web environments you will likely not have the ability to edit IIS settings.)
From the IIS manager, you can right-click on a website and Stop the website altogether. This will reject all
requests to the site, regardless of the type of resource being requested. This is a rather drastic measure, however, since
it provides the user with no feedback as to why they cannot access the site. The user attempting to connect will assume
that your server is offline because of technical problems - this may be the case, but we can send a much more positive message
to visitors by instead displaying a web page explaining that the site is currently offline, but will be back up soon.
A more user-friendly approach to taking the website offline from IIS is to instruct IIS to route all incoming requests for
the web site (or for a particular application on the site) to another URL. For example, if you have an ASP.NET application
hosted on your site at http://www.yourserver.com/MyASPNETApplication/, you could setup IIS so that all requests
to that application are rerouted to http://www.yourserver.com/OfflineMessage.htm. You have to be careful here,
though, because if you setup IIS to reroute the user to a page within the application (such as
http://www.yourserver.com/MyASPNETApplication/OfflineMessage.htm), you will be sending an infinite loop
of redirects!
To configure an application to redirect all requests to an alternate URL, go into the IIS manager, right-click on the
application, and choose Properties. From the Virtual Directory tab, indicate that the content for this application should
come from "A redirection to a URL." Then enter the URL to redirect to and check "The exact URL entered above" checkbox, as shown in the
screenshot below.
The advantage of redirecting users to an alterate URL through IIS is that all requests will be automatically
redirectly. This includes ASP.NET pages, HTML pages, images, and so on. The techniques we'll examine later in this article
are specific to ASP.NET and therefore only apply when the user is requesting an ASP.NET resource, such as an ASP.NET web
page or an ASP.NET Web Service. However, developers hosting their applications from a shared web host environment will likely
be unable to modify IIS settings, so this option is not available.
Disabling the <httpRuntime>
Each ASP.NET AppDomain has a variety of applicaiton-level settings that are customizable through the
The <httpRuntime> element.
One attribute in the <httpRuntime> element is enabled, which, as its name implies,
indicates whether the application is available or not. This value defaults to "true", but you can override the default
value in Web.config. By setting this value to "false", any request entering the ASP.NET engine for the
application will return an the default ASP.NET 404 status page.
Keep in mind that any requests not handled by the ASP.NET engine - images files, CSS files, static HTML pages, and
so on - will return as normal. Only ASP.NET resources will report a 404 status.
To illustrate taking an application offline using <httpRuntime>, update your applicaiton's
Web.config so that it looks like the following:
<configuration>
<system.web>
... Configuration settings removed for brevity ...
<httpRuntime enable="false" />
</system.web>
</configuration>
Once this change has been made, users requesting any ASP.NET resource will be greeted with the standard ASP.NET 404 error
message.
Using App_Offline.htm
Disabling the <httpRuntime> is akin to stopping IIS - it works, but it's less than ideal because it
provides no feedback to the end user. Fortunately, there is a better approach available in ASP.NET 2.0
for taking the application offline: the App_Offline.htm file. Adding a file in the application root
named App_Offline.htm automatically causes the AppDomain to recycle and modifies its behavior such that
any request for an ASP.NET resource returns the contents of the App_Offline.htm file instead (along
with an HTTP 404 status). Deleting App_Offline.htm automatically recycles the AppDomain again and the web
application is back to serving its usual content.
The main advantage of App_Offline.htm over <httpRuntime> is that with App_Offline.htm,
the content of the App_Offline.htm file is returned to the client (rather than a simple 404). So you can
place a rich App_Offline.htm file with fancy graphics and a nicely formatted message eloquently explaining why the
website is unavailable. Also, since App_Offline.htm is just a simple text file, it is easy for automated scripts
or other processes to take an ASP.NET application offline (or bring it back online).
There are some edge cases to be familiar with. First of all, the ASP.NET runtime will not return an App_Offline.htm
file if it exceeds 1 MB in size. Furthermore, if your App_Offline.htm file is too small (less than 512 bytes),
Internet Explorer will display its "friendly 404 error page" rather than the content returned by App_Offline.htm
(assuming friendly HTTP error pages are enabled in IE, which they are, by default). Fore more discussion on this issue,
see Scott Guthrie's blog entry, App_Offline.htm and
Working Around the "IE Friendly Errors" Feature.
The download at the end of this article includes a demonstration of how to create the App_Offline.htm file
programmatically from an ASP.NET page. In particular, it includes a page that only Administrators should be able to access.
From this page, the Administrator can enter a message and click a button to take the application offline. Clicking the
button has the effect of creating an App_Offline.htm file in the application's root based on a template
file also stored in the root. Long story short, the message entered by the Administrator is injected into the resulting
App_Offline.htm page.
Of course, the mere presence of App_Offline.htm prohibits access to ASP.NET pages in the application. Therefore,
it is not possible to have an ASP.NET page that an Administrator can visit to bring the site back online. Instead, the
Administrator must manually delete the App_Offline.htm, either through Windows Explorer or FTP or some other
mechanism. Since App_Offline.htm only applies to a particular ASP.NET application, it would be possible to create
a second ASP.NET application on the same server that could then create or delete the other application's App_Offline.htm
file (assuming the application creating/deleting the file is not running in medium
trust).
Creating a "Manage Offline Status" Page
Since the App_Offline.htm option does not make it easy for an Administrator to come back in and bring the
application back online, I decided to implement a third approach for taking an application offline. The impetus for this
technique came from Rick Strahl's blog entry, Taking an ASP.NET Application
Offline, and it works in both ASP.NET 1.x and 2.0 (unlike
App_Offline.htm, which is strictly a 2.0 feature). In summary, it works by defining
two Application variables (IsOffline and OfflineMessage) and two ASP.NET pages:
TemporarilyOfflineMessage.aspx - an ASP.NET page that displays the offline message. This message
includes both some boilerplate markup and the OfflineMessage Application variable.
ManageOfflineStatus.aspx - an ASP.NET page that is intended only for Administrators to access.
It allows the Administrator to alter the values of the Application variables.
The piece that fits it all together is Global.asax, which is a file that contains event handler for
application-level events. One such event is BeginRequest, which fires at the beginning of every incoming
request handled by the ASP.NET engine. I wrote code here to check to see if the application was offline (namely, if
the Application variable IsOffline is True). If so, then for any requests to pages other than
TemporarilyOfflineMessage.aspx or ManageOfflineStatus.aspx, the user is redirected to
TemporarilyOfflineMessage.aspx.
Here is the code in Global.asax in VB. The download at the end of this article includes the code in
C#, as well.
<%@ Application Language="VB" %>
<script runat="server">
Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
Application("OfflineMessage") = "This website is offline."
Application("IsOffline") = False
End Sub
Sub Application_OnBeginRequest(ByVal sender As Object, ByVal e As EventArgs)
Dim offline as Boolean = Convert.ToBoolean(Application("IsOffline"))
If offline Then
' We are in offline mode...
' See if the user is requesting one of the "safe" pages
Dim requestedUrl as string = System.IO.Path.GetFileName(Request.PhysicalPath)
Dim safePages as String() = { "ManageOfflineStatusCS.aspx", "ManageOfflineStatusVB.aspx", "TemporarilyOfflineMessage.aspx" }
For Each safePage As String In safePages
If String.Compare(requestedUrl, safePage, True) = 0 Then
Exit Sub ' match found
End If
Next
' If we reach here, we need to send the user to TemporarilyOfflineMessage.aspx
Response.Redirect("~/TemporarilyOfflineMessage.aspx")
End If
End Sub
</script>
With this code in place, it is possible for a user (hopefully only Administrators!) to take the application offline and
to bring it back online, all from a single web page. Moreover, from that web page the user can specify a custom offline
message. In short, it's very much like the App_Offline.htm approach, but with the ability to bring the
site back online from a web page within the application.
Conclusion
In this article we saw four different techniques for taking a web application offline. The most encompassing way to take
an application offline is from IIS, since that guarantees that all requests will be either rejected or rerouted to
some explanation page. However, depending on how and where your website is hosted, you may not have access to the IIS manager.
In such circumstances, there are a variety of ways to take an application offline through ASP.NET techniques, be it
<httpRuntime> settings, App_Offline.htm, or custom code. The downside to these approaches,
however, is that they only apply to ASP.NET resources.