Главная страница статей --> Хитрости при программировании php, заметки по базам данных

Обработка ошибок в ASP.NET приложении.

Источник: realcoding.net

Проблема


Во время выполнения приложения ASP.NET может возникнуть исключение, которое не обрабатывается в коде приложения, т.к. от ошибок или невнимательности никто не застрахован. :) Но стандартная страница ASP.NET, сообщая об ошибке, выглядит достаточно пугающе для рядового пользователя. Решением может выступить создание для нее дружественного интерфейса.

Решение


Для этого придется внести изменения в Global.asax. Данный файл содержит методы, обрабатывающие события уровня приложения и сессии. Нам нужно будет работать с методом Application_Error. Кроме того, нужно будет создать страницу, назовем ее Error.aspx, сообщающую о возникшей ошибке.

Код Global.asax.cs

Здесь возможно несколько подходов к реализации процесса оповещения об ошибке.

1. Сообщить пользователю об ошибке и предоставить информацию о ней. В данном случае код выглядит так:

protected void Application_Error(Object sender, EventArgs e)
{
   
try
   
{
       
//ловим последнее возникшее исключение
       
Exception lastError = Server.GetLastError();

        if (
lastError != null)
        {
            
//Записываем непосредственно исключение, вызвавшее данное, в
            //Session для дальнейшего использования
            
Session[ErrorException] = lastError.InnerException;
        }

       
// Обнуление ошибки на сервере
       
Server.ClearError();

       
// Перенаправление на свою страницу отображения ошибки
       
Response.Redirect(Error.aspx);
    }
   
catch (Exception)
    {
       
// если мы всёже приходим сюда - значит обработка исключения
        // сама сгенерировала исключение, мы ничего не делаем, чтобы
        // не создать бесконечный цикл
       
Response.Write(К сожалению произошла критическая ошибка. Нажмите кнопку Назад в браузере и попробуйте ещё раз. );
    }
}

2. Сообщить администратору


2.1. При помощи электроннной почты

protected void Application_Error(Object sender, EventArgs e)
{
   
try
   
{
       
try
       
{
            
System.Exception ex = Server.GetLastError();
            
// Собираем необходимые данные
            
String Message = Main Error + nDate & Time: +
            
DateTime.Now.ToString(F) + nnURL: + Request.Path +
            
nnQUERY: + Request.QueryString + nnMESSAGE: +
            
ex.Message + nnBROWSER: + Request.Browser.Browser +
            
nnIP Address: + Request.UserHostAddress;

            
//Добавляем информацию о предыдущей посещенной странице
            
if(Context.Request.UrlReferrer != null)
            {
               
Message += nnReferer: +
                
Context.Request.UrlReferrer.ToString();
            }

            
//Добавляем информацию о пользователе, в случае если успешно прошел процесс аутентификации
            
if(Context.User.Identity.IsAuthenticated)
            {
               
Message += nnUser: + Context.User.Identity.Name;
            }

            
Message += nnnnEXCEPTION: + ex.ToString();
            
System.Web.Mail.MailMessage mail = new System.Web.Mail.MailMessage();
            
mail.To = [e-mail адрес администратора];
            
mail.Subject = Error in the Site;
            
mail.Priority = System.Web.Mail.MailPriority.High;
            
mail.BodyFormat = System.Web.Mail.MailFormat.Text;
            
mail.Body = Message;
            
// Здесь необходимо указать используемый SMTP сервер
            
System.Web.Mail.SmtpMail.SmtpServer=[адрес SMTP сервера];
            
System.Web.Mail.SmtpMail.Send(mail);
        }
       
catch {}
       
// Обнуление ошибки на сервере
       
Server.ClearError();
       
// Перенаправление на статическую html страницу, сообщающую об ошибке
        // никаких данных об произошедшей ошибке ей не передается
       
Response.Redirect(Error.html);
    }
   
catch
   
{
       
// если мы всёже приходим сюда - значит обработка исключения
        // сама сгенерировала исключение, мы ничего не делаем, чтобы
        // не создать бесконечный цикл
       
Response.Write(К сожалению произошла критическая ошибка. Нажмите кнопку Назад в браузере и попробуйте ещё раз. );
    }
}

2.2. При помощи записи сообщения в журнал событий Windows

protected void Application_Error(Object sender, EventArgs e)
{
   
try
   
{
       
// Наименование ресурса, вызвавшего ошибку
       
string EventSourceName = ErrorSample;
       
// Наименование LogView
       
string logName = Application;
       
       
System.Exception ex = Server.GetLastError();

       
System.Diagnostics.EventLog Log = new System.Diagnostics.EventLog(logName);
       
Log.Source = EventSourceName;
       
Log.WriteEntry(ex.InnerException.Message, System.Diagnostics.EventLogEntryType.Error);   
   
       
// Обнуление ошибки на сервере
       
Server.ClearError();
       
// Перенаправление на статическую html страницу, сообщающую об ошибке
        // никаких данных об произошедшей ошибке ей не передается
       
Response.Redirect(Error.html);
    }
   
catch (Exception ex)
    {
       
// если мы всёже приходим сюда - значит обработка исключения
        // сама сгенерировала исключение, мы ничего не делаем, чтобы
        // не создать бесконечный цикл
       
Response.Write(К сожалению произошла критическая ошибка. Нажмите кнопку Назад в браузере и попробуйте ещё раз. );
    }
}

Здесь следует заметить, что зачастую приложение ASP.NET имеет достаточно ограниченный набор прав (что, в принципе, правильно с точки зрения безопасности). В связи с этим мы не сможем программно создать Event Source или проверить его существование в журнале событий Windows, если не будем использовать имперсонацию (impersonate). Решением может выступать ручное создание Event Source. Для этого внесем в реестр новый ключ, воспользовавшись программой regedit.

Нам необходимо добавить новый ключ по адресу

HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesEventlogApplication.

Его имя должно совпадать с указанным в коде. В нашем случае это ErrorSample.

3. При помощи комбинации вышеперечисленных методов


Страница Error.aspx

Страница Error.aspx, как уже говорилось выше, должна непосредственно выводить сообщение об ошибке. Для этого добавим на нее Label и назовем его lblMessage. Обработку исключения (напомню, что мы поместили его в сессию), будем производить в методе Page_Load. Его текст приведен ниже.

private void Page_Load(object sender, System.EventArgs e)
{
   
try
   
{
       
// возьмем информацию об исключении из сессии
       
Exception exc=(Exception)Session[ErrorException];
       
string errorMsg = exc.Message;
       
string pageErrorOccured = Context.Request.UrlReferrer.ToString();
       
string exceptionType = exc.GetType().ToString();
       
string stackTrace = exc.StackTrace;
       
       
// очистим переменную сессии
       
Session[ErrorException] = null;

       
//отобразим пользователю общее сообщение об ошибке
       
lblMessage.Text = К сожалению, произошла ошибка выполнения приложения.<br/><br/>;
       
lblMessage.Text =String.Format({0} Чтобы попробовать ещё раз,
        кликните <a href={1}>здесь</a>.<br/><br/>
,lblMessage.Text,
       
pageErrorOccured);

       
//добавим конкретное сообщение об
       
lblMessage.Text = lblMessage.Text +
       
Error Message: + errorMsg +n+
       
Page Error Occurred: + pageErrorOccured + n+
       
ExceptionType: + exceptionType +n+
       
Stack Trace: + stackTrace;
    }
   
catch (Exception ex)
    {
       
//если исключение вызвано кодом, написанным выше
        //выведем сообщение об ошибке и StackTrace
       
lblMessage.Text = ex.Message+ +ex.StackTrace;
    }
}

Альтернатива


Следует заметить, что намного эффективнее будет использовать один из параметров файла web.config. Это позволит быстро (без изменения кода), менять ссылку страницы с сообщениями об ошибке или вообще убрать ее, в случае необходимости. Сссылка на нее задается с помощью атрибута defaultRedirect. Кроме того, при использовании данного атрибута в коде, следует убрать строки

// Обнуление ошибки на сервере
Server.ClearError();

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

// Перенаправление на страницу сообщающую об ошибке
Response.Redirect(Error.aspx);

Пример настройки web.config:

<customErrors mode=On defaultRedirect=error.aspx/>

Так же, сужествует дополнительная возможность: перенаправление на определенную страницу в зависимости от кода HTTP ошибки. Это позволяет делать параметр “error“. Его атрибут statusCode задает код ошибки, а redirect задает страницу, на которую следует перенаправить пользователя. Например, в случае, если запрашиваемый ресурс не найден (код ошибки 404), перенаправим пользователя на страницу Error404.html, оповещающая пользователя о случившемся происшествии. Web.config будет выглядить так:

<customErrors mode=On defaultRedirect=error.aspx>
  <
error statusCode=404 redirect=Error404.html/>
</
customErrors>



Похожие статьи:
- Создавая свой веб-сайт, не превращайте его в призрака
- Аккуратный HTML
- HTML_AJAX в действии
- Создаем статистику для сайта своими руками на ASP.NET
- Почему веб-зеваки ничего не стоят
- Всплывающее меню для одностраничного портала
- Сложные графики и диаграммы в ASP.NET. Часть третья - HttpHandler/System.Drawing
- Категориальное упорядочение результатов запроса
- Средства безопасности ASP.NET. Аутентификация
- XML+MSSQL+ASP.NET. Часть 1.
- Концептуальный подход к дизайну сайта
- Разница между HttpModule и HttpHandler
- Очищаем HTML от лишних знаков


Оглавление | Обсудить на форуме | Главная страница сайта | Карта сайта |

Контакты
Редакция:
[0.001]