15

我为在 IIS7 / Win2008 64 位上运行的 ASP.NET MVC2 应用程序创建了一个app_offline.htm文件,并确保它超过 512 字节(现在是 2KB)。在我运行 Visual Studio 2010 的开发机器上,它的工作原理很吸引人,但是当我将它放在生产机器上时,我得到的只是一般的 HTTP 500 错误,说“由于发生内部服务器错误,无法显示页面。”

特别奇怪的是,我没有在应用程序事件日志中记录任何内容,ELMAH 也没有收到任何内容。我已经禁用了自定义错误,为文件放置了 FormsAuthentication 位置异常,确保我没有引用任何其他文件(图像等),但没有任何修复它。

我已经阅读了关于 SO 的每一篇文章,并在谷歌上搜索了几个小时,但无法弄清楚这一点。有什么想法可能是错的吗?我在这里拔头发...

4

2 回答 2

12

更新:
你的 web.config 中有这个吗?

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.web>
        <httpRuntime waitChangeNotification="300" maxWaitChangeNotification="300"/>
    </system.web>
    <system.webServer>
        <modules runAllManagedModulesForAllRequests="true" />
    </system.webServer>
</configuration>

但还有一个问题。

ASP.NET 将在 web.config 更改后立即卸载应用程序,但它实际上不会重新加载它并应用“waitChange...”设置,直到发出请求。因此,您仍然可以将 app_offline.htm 和 web.config 放入其中,如果在 dll 仅复制一半时发生第一个请求,则会发生异常。雪上加霜,该异常将持续存在,直到您替换临时 web.config 或“waitChange...”时间的总持续时间到期!

要绕过最后一个障碍,您需要在上传临时 web.config 之后但在开始部署应用程序文件之前向应用程序发出请求。完整的过程如下:

  1. 添加 app_offline.htm
  2. 将应用程序的 web.config 替换为临时 web.config(如上)
  3. 请求站点上的任何 ASP.NET 资源,以便“应用”新的 waitChangeNotification*
  4. 进行任何必要的文件系统更改(部署 bin dll、其他站点文件)
  5. 将临时 web.config 替换为原始应用程序 web.config
  6. 删除 app_offline.htm

*您可能会对步骤 2-3 中发生的情况提出异议,因为 ASP.NET 在步骤 1 之后关闭了应用程序。事实上,从我的事件查看器中并没有显示 web.config 更改已注册或“应用”,因为第 2 步或第 3 步,但更新后的 waitChangeNotification 设置确实在第 3 步之后应用。

更多 app_offline.htm 问题

ASP.NET MVC 的 App_offline.htm 陷阱

于 2011-03-01T15:20:21.180 回答
4

我想出了一个对我们的部署 100% 有效的解决方案,所以我想我会分享它。

此解决方案将customErrors部分添加到web.config。这将捕获任何未处理的异常。它重定向到App_Offline.htm,它会刷新直到应用程序重新联机。所以用户得到了一个很好的加载器,当应用程序可用时它就会消失。

我希望这是有帮助的 :)

批处理文件

copy "C:\www\_App_Offline.htm" "C:\www\App_Offline.htm"
copy /y "C:\www\App_Offline.config" "C:\www\Web.config"

Rem do deploy/publish actions

Rem Note: Our publish replaces/restores the Web.config. You should do that here.
del "C:\www\App_Offline.htm"

App_Offline.config

<?xml version="1.0"?>
<configuration>
  <system.web>
    <httpRuntime waitChangeNotification="100" maxWaitChangeNotification="100"/>
    <customErrors defaultRedirect="App_Offline.htm" mode="On">
    </customErrors>
  </system.web>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
  </system.webServer>
</configuration>

_App_Offline.htm

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <title>Application Offline</title>
    <meta charset="UTF-8">
    <style>
        .facebook_blockG { background-color: none; border: 3px solid #D6D6D6; float: left; height: 40px; margin-left: 7px; width: 24px; opacity: 0; -moz-animation-name: bounceG; -moz-animation-duration: 1.3s; -moz-animation-iteration-count: infinite; -moz-animation-direction: linear; -moz-transform: scale(0.7); -webkit-animation-name: bounceG; -webkit-animation-duration: 1.3s; -webkit-animation-iteration-count: infinite; -webkit-animation-direction: linear; -webkit-transform: scale(0.7); -ms-animation-name: bounceG; -ms-animation-duration: 1.3s; -ms-animation-iteration-count: infinite; -ms-animation-direction: linear; -ms-transform: scale(0.7); -o-animation-name: bounceG; -o-animation-duration: 1.3s; -o-animation-iteration-count: infinite; -o-animation-direction: linear; -o-transform: scale(0.7); animation-name: bounceG; animation-duration: 1.3s; animation-iteration-count: infinite; animation-direction: linear; transform: scale(0.7); }
        #blockG_1 { -moz-animation-delay: 0.39s; -webkit-animation-delay: 0.39s; -ms-animation-delay: 0.39s; -o-animation-delay: 0.39s; animation-delay: 0.39s; }
        #blockG_2 { -moz-animation-delay: 0.52s; -webkit-animation-delay: 0.52s; -ms-animation-delay: 0.52s; -o-animation-delay: 0.52s; animation-delay: 0.52s; }
        #blockG_3 { -moz-animation-delay: 0.65s; -webkit-animation-delay: 0.65s; -ms-animation-delay: 0.65s; -o-animation-delay: 0.65s; animation-delay: 0.65s; }

        @-moz-keyframes bounceG {
            0% { -moz-transform: scale(1.2); opacity: 0.6; }

            100% { -moz-transform: scale(0.7); opacity: 0; }
        }

        @-webkit-keyframes bounceG {
            0% { -webkit-transform: scale(1.2); opacity: 0.6; }

            100% { -webkit-transform: scale(0.7); opacity: 0; }
        }

        @-ms-keyframes bounceG {
            0% { -ms-transform: scale(1.2); opacity: 0.6; }

            100% { -ms-transform: scale(0.7); opacity: 0; }
        }

        @-o-keyframes bounceG {
            0% { -o-transform: scale(1.2); opacity: 0.6; }

            100% { -o-transform: scale(0.7); opacity: 0; }
        }

        @keyframes bounceG {
            0% { transform: scale(1.2); opacity: 0.6; }

            100% { transform: scale(0.7); opacity: 0; }
        }
    </style>
</head>
<body>

    <div id="overlay" class="trans">
        <div id="overlay-inner" class="trans login">
            <h1 style="line-height:1em; font-size:30pt">Application Offline</h1>
            <h2 style="line-height:1em; width:70%; margin:auto">application is offline for maintenance</h2>
            <div style="width: 128px; margin:40px auto">
                <div id="blockG_1" class="facebook_blockG">
                </div>
                <div id="blockG_2" class="facebook_blockG">
                </div>
                <div id="blockG_3" class="facebook_blockG">
                </div>
            </div>
        </div>
    </div>

    <script type="text/javascript">
        function getParameterByName(name) {
            name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
            var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
                results = regex.exec(location.search);
            return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
        }
        setTimeout(function () {
            var loc = getParameterByName('aspxerrorpath');
            loc = (loc) ? window.location.protocol + '//' + window.location.host + loc : window.location.href;
            window.location.assign(loc);
        }, 1500);
    </script>
</body>
</html>
于 2014-10-10T18:46:35.670 回答