Кнопка иногда перенаправляет на «Эта страница не может быть отображена» - PullRequest
1 голос
/ 04 февраля 2012

У меня есть веб-приложение ASP.NET c #, опубликованное на нашем сервере.Он состоит из трех страниц, каждая из которых имеет форму, похожую на 3-страничный логин.После проверки формы третьей страницы она отправляет пользователя на другой сайт.Вот небольшая диаграмма, поэтому я могу объяснить ее лучше:

NamePage ---> DateOfBirthPage ---> IDNumberPage ---> OtherSite

Это прекрасно работаетво всех наших тестах развития и стресс-тестах.Однако после того, как мы запустили его в производство, иногда, когда нажимается кнопка «Далее» на IDNumberPage, пользователь видит «Эта страница не может быть отображена» с помощью кнопки «диагностировать проблемы с подключением».Когда это происходит для одного пользователя, такая же проблема возникает для всех пользователей (то есть, когда это происходит, никто не может полностью аутентифицироваться).NamePage и DateOfBirthPage всегда работают, и когда происходит сбой, ссылка IDNumberPage не изменяется, предполагая, что сбой происходит на этой стороне приложения, а не после его перенаправления на OtherSite.У меня отключены дружественные HTTP-ошибки, но на странице не отображаются ошибки.Если мы зайдем на сервер и перезапустим приложение, оно снова заработает.

Огорчает то, что мы не можем воспроизвести эту ошибку, чтобы увидеть, как / почему она происходит.

Некоторые вещи, которыезаслуживают внимания:

  • Каждая страница использует один запрос к базе данных сервера MS SQL
  • Каждая страница передает до 4 переменных сеанса (только маленькие строки, содержащие то, что было введено в форму текстового поля напредыдущая страница (ы))
  • Сессия прекращается при нажатии последней "следующей" кнопки.
  • Все результирующие наборы / соединения / команды закрываются перед перенаправлением.
  • Перенаправления используют перегруженную версию, используя Response.Redirect(siteName, false)

Извините, если все это очень расплывчато, но сама проблема сделала странно хорошую работу по сокрытию от нас.Мы пытались забить сервер тестовыми запросами (много раз, много за определенный период времени и т. Д.) И различными комбинациями входа / попытки пробить страницу в целом, но безрезультатно.Кто-нибудь может предложить некоторые вещи, чтобы попытаться диагностировать / исправить / воспроизвести эту проблему?

Редактировать: Функция щелчка по выделенному коду IDNumberPage, которая вызывает проблему:

{ SqlConnection dbconn = new SqlConnection(Application["dbconn"].ToString());
                SqlCommand sqlValidate = dbconn.CreateCommand();
                dbconn.Open();
                sqlValidate.CommandText = "SELECT lastName, csn FROM Demographics WHERE lastName = '" + Session["lastName"].ToString() + "' " +
                    "AND dob = '" + Session["dobCheck"].ToString() + "' AND mrn = " + strMRN;
                SqlDataReader results = sqlValidate.ExecuteReader();
                if (results.HasRows)
                {
                    string csn = "";
                    while (results.Read())
                    {
                        if (!String.IsNullOrEmpty(results["csn"].ToString()))
                        {
                            csn = results["csn"].ToString();
                            break;
                        }
                    }
                    string url = Application["surveyUrlString"] + "&lastname=" + Session["lastName"].ToString() + "&mrn=" + strMRN + "&dobday=" + Session["dobday"].ToString() 
                                + "&dobmonth=" + Session["dobmonth"].ToString() + "&dobyear=" + Session["dobyear"].ToString() + "&csn=" + csn;
                    results.Close();
                    dbconn.Close(); 
                    Response.Redirect(url, false);
}

Ответы [ 2 ]

5 голосов
/ 04 февраля 2012

Проблема связана с утечкой SQL-соединений.

Вы неправильно распределяете свои ресурсы.Со временем они будут складываться в пуле соединений, пока вы не достигнете точки, когда пул переполняется, и ваше приложение умирает.Сброс, очевидно, решит проблему.

Также эта проблема может не будет отображаться в «стрессовых» тестах в зависимости от того, как именно вы тестируете приложение.

Решение состоит в том, чтобы переформатировать этот код для обработкиваша база данных звонит лучше.

{ 
    string url = string.empty;

    using (SqlConnection dbconn = new SqlConnection(Application["dbconn"].ToString())) {
        using (SqlCommand sqlValidate = dbconn.CreateCommand()) {
            dbconn.Open();
            sqlValidate.CommandText = "SELECT lastName, csn FROM Demographics WHERE lastName = '" + Session["lastName"].ToString() + "' " +
                "AND dob = '" + Session["dobCheck"].ToString() + "' AND mrn = " + strMRN;
            using (SqlDataReader results = sqlValidate.ExecuteReader()) {
                if (results.HasRows) {
                    string csn = "";
                    while (results.Read())
                    {
                        if (!String.IsNullOrEmpty(results["csn"].ToString()))
                        {
                            csn = results["csn"].ToString();
                            break;
                        }
                    }
                    url = Application["surveyUrlString"] + "&lastname=" + Session["lastName"].ToString() + "&mrn=" + strMRN + "&dobday=" + Session["dobday"].ToString() 
                            + "&dobmonth=" + Session["dobmonth"].ToString() + "&dobyear=" + Session["dobyear"].ToString() + "&csn=" + csn;
                }
            } // sqldatareader
        } // using sqlcommand
    } // using sqlconnection
    if (!String.IsNullOrEmpty(url)) {
        Response.Redirect(url, false);
    }
}

обратите внимание, что вы не перенаправляете до тех пор, пока все не будет очищено.

SqlConnection, SqlCommand и SqlDataReader все орудия IDisposable.Вы должны правильно убирать после использования, иначе ресурсы останутся зависшими.«Лучший» способ сделать это - заключить их в предложение using.Это гарантирует, что они удаляются должным образом после выхода из блока кода, поскольку они не собираются мусором, как другие объекты.


Также обратите внимание, что приведенный выше код имеет хорошие побочные преимущества.А именно, в случае ошибки он все равно уберется за вами.Принимая во внимание, что исходный код, который был опубликован, явно утечет в случае, если сервер БД не отвечает или выдает какой-либо тип ошибки при выполнении запроса.

Запрос может давать ошибку в зависимости от значений, содержащихся в dboCheck,параметры фамилия и мрн.Например, что, если для поля dobCheck было передано «BOB», или для mrn ничего не передано ... Если dob - это поле даты и времени в вашей базе данных, тогда запрос выдаст ошибку, которая приведет к утечке соединения.Сделайте это достаточное количество раз, и ваш сайт не работает.

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


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

0 голосов
/ 04 февраля 2012

Хороший ответ Крис, один вопрос - не пропущены ли операторы .Close () в операторах Using ?.Как для соединения, так и для чтения данных:

         results.Close();
        } // using sqldatareader
       } // using sqlcommand
      dbconn.Close();
     } // using sqlconnection    
...