Server.Transfer вызывает исключение сеанса

В моем глобальном я имею следующий код для обработки, когда возникает ошибка

//[..] code goes here
  Server.Transfer("~/Error.aspx?ErrorID=" + errorId);

Раньше он был Response.Redirect, который отлично работал, за исключением того, что он менял URL-адрес (вот почему я хочу использовать Server.Transfer)

К сожалению, теперь, когда он пытается загрузить страницу "Ошибка", он сбой на главной странице, когда он пытается ссылаться на Session

HttpException:
Состояние сеанса может использоваться только тогда, когда для параметра enableSessionState установлено значение true, либо в файле конфигурации, либо в директиве "Страница". Пожалуйста, также убедитесь, что System.Web.SessionStateModule или пользовательское состояние сеанса модуль включен в \\ раздел конфигурации приложения.

У меня есть enableSessionState как в моей конфигурации, так и на моей странице.

Я также нашел некоторые ссылки, которые предлагают использовать Context.RewritePath - это просто приводит к загрузке пустой страницы.

Использование Response.Redirect работает отлично и, как ожидалось, поэтому я предполагаю, что Server.Transfer - проблема здесь. Что это?

Код EDIT:

protected void Application_Error(object sender, EventArgs e)
        {

            lock (_lockMe)
            {
                Exception ex = Server.GetLastError();

                if (ex != null)
                {
                    if (ex.InnerException != null)
                        ex = ex.InnerException;

                    ErrorLoggingManager.AddError(ex, new MembershipData(), ...); //etc
                }

                Server.ClearError();

                   //Some other database code for cleaning up some stuff when an error happens

                }

                try
                {
                    if (Response != null)
                    {
                        //Get the last error logged
                        MyDataContext db = new MyDataContext();
                        int errorId = db.LoggedErrors.OrderByDescending(le => le.ErrorId).Select(le => le.ErrorId).FirstOrDefault();

                        Server.Transfer("~/Error.aspx?ErrorID=" + errorId); 
                    }
                }
                catch (Exception)
                {
                }
            }

Ответы

Ответ 1

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

Точка 1. Прежде всего, вам нужно проверить, есть ли SessionState enabled для страниц. Вы можете установить их глобально в файле web.config. Попробуйте snippet, приведенную ниже в web.config

<configuration>   
   <system.web>
   <pages enableSessionState="true" />
  </system.web>
</configuration>

Пункт 2. И поставьте Redirection в Application_Error в Global.asax.

public void Application_Error(object sender, EventArgs e)
{
     HttpApplication app = (HttpApplication)sender;
     app.Server.Transfer("~/Error.aspx?ErrorID=" + errorId,true);
 }

Точка 3. Также проверьте, правильно ли установлен SessionState в IIS.

Детали находятся на MSDN, чтобы включить sessionstate

Надеюсь, это поможет..!!!

Ответ 2

Из того, что я понимаю, Server.Transfer отправляет содержимое другой страницы клиенту, а не запрошенному контенту. Если это так, то мне интересно, не связано ли это с применением главной страницы страницы ошибки? У меня была аналогичная ошибка несколько лет назад с более ранними технологиями, и оказалось, что главной странице не понравилось то, что я пытался сделать.

Надеюсь, это поможет хотя бы указать на решение.

Ответ 3

Вот в чем проблема:

Если есть исключение отображения страницы (например, "Файл не найден" ), то Server.Transfer завершает сеанс. Это связано с тем, что он вызывается во время рендеринга страницы.

Пока вы не добавляете заголовки до возникновения ошибки, Response.Redirect будет работать нормально; если вы, тем не менее, используете Response.AppendHeader, то Response.Redirect не будет работать во время рендеринга страницы.

Попробуйте вместо этого использовать HttpContext.Current.RewritePath. Это должно исправить все эти проблемы. По какой-то причине RewritePath() не заботится о том, чтобы страница не закончила рендеринг.

Ответ 4

Почему бы просто не использовать customErrors в web.config для выполнения перенаправления?

<customErrors mode="Off" defaultRedirect="~/Common/Error.aspx">
  <error statusCode="403" redirect="~/SM_AccessDenied.aspx" />
  <error statusCode="404" redirect="~/Common/FileNotFound.aspx" />
</customErrors>

Ответ 5

У меня была такая же проблема в другом контексте некоторое время назад. Я не знаю, является ли это вашим делом, но если вы используете IIS7 в Windows 2008, помимо настройки enableSessionState=true в вашем web.config, вы должны поместить свои модули в раздел <system.webServer>, а не <system.web>. Изменение этой мелочи разрешило это для меня.

Ответ 6

Почему бы вам не попробовать:

В методе Server.Transfer также есть второй параметр - preserveForm. Если вы установите для этого значение значение True, используя оператор, такой как Server.Transfer( "WebForm2.aspx", True), существующая строка запроса и любые переменные формы будут по-прежнему доступны для страницы, на которую вы переходите.

Итак, я думаю, что делать так, что ваш сеанс не истечет.

Server.Transfer("~/Error.aspx?ErrorID=" + errorId,True);

Ответ 7

Ошибка, с которой вы сталкиваетесь, связана с тем, что вы используете параметр строки запроса. В документах msdn

However, the path parameter must not contain a query string, or ASP returns an error.

http://msdn.microsoft.com/en-us/library/ms525800%28v=vs.90%29.aspx

Его около 3/4 пути вниз по странице чуть выше Требования.

Несмотря на то, что в документах упоминается asp. и не asp.net, имейте в виду, что состояние сеанса является особенностью IIS и обрабатывается до того, как когда-либо вызывается asp.net.

Ответ 8

@user2110845: Я столкнулся с подобной проблемой несколько месяцев назад. проблема заключалась в наличии подчеркивания в названии веб-сайта. Мы развертывали веб-сайт в IIS с двумя разными именами хостов (добавив две записи через параметр "Изменить привязки" на веб-сайте). Были указаны имена хостов: abc_ts, abc_is. Когда подчеркивание было удалено, проблема сеанса была решена. Кажется, что некоторые символы не разрешены в имени узла веб-сайта. Проверьте, не является ли это вашей проблемой. Я нашел ответ здесь: ссылка (отметьте "обновление 2" в статье)

Ответ 9

Вы не упомянули, какую версию ASP.NET вы используете, но были некоторые изменения между 2.0 и 3.5 в том, как необработанные исключения барботировали свой путь через веб-приложение ASP.NET, а затем IIS.

В некоторых других случаях, когда вы очищаете ошибку, вы не устанавливаете Context.Response.TrySkipIisCustomErrors = true;. Хотя этот конкретный флаг не может иметь ничего общего с вашей проблемой (и доступен только для 3.5+), это также может помочь справиться с тем, что потенциально две страницы ошибок за кулисами, которые скрывают реальную проблему. Несмотря на это, это сэкономит вам много горя (по крайней мере, если вы используете 3.5+) с другими потенциальными проблемами. Просмотрите два сообщения, которые я написал несколько лет назад, которые могут быть полезны: хотя они не охватывают обработку сеанса, они охватывают несколько подпрограмм песни и танца, которые я должен был выполнить, чтобы получить правильную обработку 500 и 404 в различных версиях ASP.СЕТЬ. Возможно, вы столкнетесь с чем-то, что поможет вам продвинуться дальше, если не так, как есть.

http://www.andornot.com/blog/post/Errors-Sending-the-Right-Message-(Redux-Covering-ASPNET-3540).aspx

http://www.andornot.com/blog/post/Errors-Sending-the-Right-Message.aspx