I have created an app_offline.htm file for an ASP.NET MVC2 application running on IIS7 / Win2008 64-bit, and ensured that it's over 512 bytes (it's 2KB right now). On my dev box running Visual Studio 2010, it works like a charm, but when I put it on the production box, all I get is the generic HTTP 500 error saying "The page cannot be displayed because an internal server error has occurred."

Is there more information in the server's event log?
–
AUSteveFeb 8 '11 at 2:19

No, that's the strange thing - there is nothing thrown on the server at all, not in the App event log or the System event log.
–
JoshFeb 8 '11 at 12:21

Have you tried accessing the site from localhost? that sometimes shows more detail. also have tried firefox and/or switching off friendly http error messages in IE so it shows you the actual error.
–
Simon HalseyFeb 24 '11 at 14:18

Not from localhost at the server, but I'll try that. I've tried in Firefox and Chrome but I don't get anything but a single line of simple text.
–
JoshFeb 25 '11 at 0:18

ASP.NET will unload the application as
soon as the web.config is changed, but
it won’t actually reload it and apply
the “waitChange…” settings until a
request is made. So you could still
drop the app_offline.htm and
web.config in, and if the first requst
occurs while a dll is only half
copied, the exception will occur. To
add insult to injury, the exception
will persist until you replace the
temporary web.config or the total
duration of your “waitChange…” time
expires!

To get around this final hurdle, you’d
need to make a request to the
application after uploading the
temporary web.config, but before you
start deploying the application files.
The complete process is as follows:

Request any ASP.NET resource on the site so the new
waitChangeNotification gets “applied”*

Make any file system changes necessary (deploy bin dlls, other site
files)

Replace temporary web.config with the original application
web.config

Delete app_offline.htm

*You may dispute what happens in step 2-3, since ASP.NET shuts down the
application after step 1. Indeed, it
does not appear from my event viewer
that the web.config change is
registered or “applied” as a result of
either step 2 or 3, but nevertheless
the updated waitChangeNotification
settings do get applied after step 3.

I came up with a solution that works 100% for our deploys, so I thought I'd share it.

This solution adds a customErrors section to the web.config. This will catch any unhandled exceptions. It redirects to the App_Offline.htm, which refreshes until the application comes back online. So the user gets a nice loader that goes away when the application becomes available.