App_offline.htm бросает ошибки HTTP 500 на коробку производства

Я создал файл app_offline.htm для приложения ASP.NET MVC2, работающего на 64-разрядном сервере IIS7/Win2008, и обеспечил его более 512 байт (сейчас он составляет 2 КБ). В моем блоке dev, в котором работает Visual Studio 2010, он работает как шарм, но когда я помещаю его в поле для производства, все, что я получаю, - это общая ошибка HTTP 500, в которой говорится: "Страница не может быть отображена, потому что произошла ошибка внутреннего сервера".

Что особенно странно, так это то, что я ничего не регистрировал в журнале событий приложений, и ELMAH ничего не выбирает. Я отключил пользовательские ошибки, поместил исключения местоположения FormsAuthentication для файла, гарантировал, что я не ссылаюсь ни на какие другие файлы (изображения и т.д.), Но ничего не исправляет.

Я читал каждый пост в SO и Googled часами и не могу понять это. Какие-нибудь идеи, что может быть неправильным? Я тяну свои волосы здесь...

Ответы

Ответ 1

UPDATE:
У вас есть это в вашем 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 in, и если первое требование происходит, когда dll - только половина Скопировано исключение. к добавить оскорбление к травме, исключение будет сохраняться до тех пор, пока вы не замените временный web.config или общий продолжительность вашего "waitChange..." истекает!

Чтобы обойти это последнее препятствие, youd необходимо подать запрос на после загрузки временный web.config, но перед вами начните развертывание файлов приложений. Полный процесс выглядит следующим образом:

  • Добавить app_offline.htm
  • Замените приложения web.config временным web.config(как указано выше)
  • Запросить любой ресурс ASP.NET на сайте, чтобы новый waitChangeNotification получает "применяется" *
  • Необходимо внести необходимые изменения в файловую систему (развернуть bin dll, другой сайт файлы)
  • Заменить временный web.config исходным приложением web.config
  • Удалить app_offline.htm

* Вы можете оспорить, что происходит на шаге 2-3, поскольку ASP.NET отключает приложения после шага 1. Действительно, это не отображается из моего средства просмотра событий что изменение web.config зарегистрировано или "применено" в результате либо на этапе 2 или 3, но тем не менее обновленная функция waitChangeNotification настройки будут применяться после шага 3.

Больше проблем app_offline.htm

App_offline.htm getchas с ASP.NET MVC

Ответ 2

Я придумал решение, которое работает на 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>