Каковы окончательные рекомендации для пользовательской обработки ошибок в ASP.NET MVC 3?

44

Процесс пользовательской обработки ошибок в ASP.NET MVC (в данном случае 3) кажется невероятно запущенным. Я прочитал различные вопросы и ответы здесь, в Интернете, на страницах справки для различных инструментов (таких как Elmah), но я чувствую, что прошел полный круг и все еще не могу найти лучшее решение. С вашей помощью, возможно, мы сможем установить новый стандартный подход к обработке ошибок. Я хотел бы сделать вещи простыми и не перегружать это.

Вот мои цели:

Для ошибок / исключений сервера:

  1. Отобразить информацию об отладке в dev
  2. Показать дружественную страницу с ошибкой в ​​производстве
  3. Регистрируйте ошибки и отправляйте их администратору по электронной почте.
  4. Возврат 500 HTTP-кода состояния

Для 404 Not Found ошибок:

  1. Показать дружественную страницу ошибок
  2. Регистрируйте ошибки и отправляйте их администратору по электронной почте.
  3. Возврат 404 HTTP код состояния

Есть ли способ достичь этих целей с помощью ASP.NET MVC?

RyanW
источник
2
Я бы хотел, чтобы этот вопрос был перенесен НАЗАД на SO, чтобы он мог получить больше ответов. Я ищу закодированные ответы.
Шон Маклин
@ Шон Это вряд ли произойдет. Вопрос здесь больше по теме, чем по SO, и на него есть принятый ответ. Вопросы также обычно не переносятся по техническим причинам. Если вам нужна помощь с кодированием конкретного подхода к обработке ошибок, пожалуйста, откройте новый вопрос о StackOverflow. В противном случае «закодированные ответы» могут быть слишком широкими критериями, чтобы быть полезными или подотчетными. И последнее, но не менее важное: лучший способ привлечь внимание модератора к вопросу - пометить его. Ваш комментарий здесь, вероятно, остался бы незамеченным, если бы он не отключил авто-флаг, увеличив количество комментариев до 20.
Адам Лир
Раньше здесь было около 10 комментариев, куда они все делись?
RyanW
Я нашел решение, которое соответствует вашим целям. У меня есть это как другой ответ на SO: stackoverflow.com/questions/6508415/…
Джесси Уэбб
1
@ Анна, я согласен с Шоном. Я нашел эту страницу только через Google. Обратите внимание, что почти все ответы ниже содержат ссылки НАЗАД на переполнение стека. Для меня это говорит о многом, потому что это должно было быть оставлено там в первую очередь.
Ребекка

Ответы:

23

Я поделюсь тем, как я это сделал, это было частью первоначального вопроса.

Во-первых, проблемы, с которыми я столкнулся:

  1. При включенной customErrors (т.е. в рабочем состоянии) глобальный HandleErrorатрибут поглощает исключения и отображает ваше представление об ошибке, но затем вы не можете зарегистрировать его с помощью дополнительного инструмента, такого как elmah, поскольку elmah никогда его не видит. Я полагаю, вы можете записать это в своем представлении, но это мнение, которое кажется неправильным. Глобальный атрибут HandleError появился в шаблоне проекта MVC 3 RTM Visual Studio.

  2. customErrors с URL для конечных точек MVC возвращает 302 кода состояния. Существует свойство redirectmode, но вы не можете сопоставить URL-адреса mvc в customErrors и использовать режим ResponseRewrite. ( https://stackoverflow.com/questions/781861/customerrors-does-not-work-when-setting-redirectmode-responserewrite/3770265#3770265 )

  3. Полное отсутствие пользовательских ошибок и обработка всего пользовательского в вашем приложении приводит к большой сложности, IMO. (Я любил это: https://stackoverflow.com/questions/619895/how-can-i-properly-handle-404s-in-asp-net-mvc/2577095#2577095 , но это было не правильно для нашего проекта)

Мое решение

Я взял MVC из уравнения полностью. Я удалил HandleErrorAttributeглобальный фильтр в global.asax и сконцентрировался полностью на конфигурации customErrors, перенеся ее на использование перенаправлений WebForm и переключившись на режим перенаправления ResponseRewrite, чтобы избежать кодов ответа 302 HTTP.

<customErrors mode="On" defaultRedirect="/Error.aspx" redirectMode="ResponseRewrite">
  <error statusCode="404" redirect="/NotFound.aspx" />
</customErrors>

Затем в NotFound.aspxсобытии page_load установите Response.StatusCodeзначение 404, а в файле Error.aspx установите код 500.

Полученные результаты:

Цели для обоих были достигнуты с помощью журналов Elmah, дружественной страницы ошибок и кода состояния с одной строкой кода на выделенных кодах. Мы не делаем это «MVC Way», как это делает более раннее решение, но я согласен с этим, если это две строки кода.

RyanW
источник
5

Я думаю, что MVC, ASP и ваша любимая среда ведения журналов / обработки исключений могут справиться с вашими задачами. ELMAH и Enterprise Library предоставляют простую в использовании обработку исключений и ведение журналов, так что выбирайте свои любимые ... Я не буду вдаваться в плюсы и минусы каждого из них.

ПРИМЕЧАНИЕ: вы не можете отобразить дружественную страницу с ошибкой И вернуть HTTP 404 или 500, как подсказывает ваш вопрос. Когда вы возвращаете дружественную страницу ошибок, HTTP-код, возвращаемый вашему браузеру, будет 302. Это перенаправление на дружественную страницу ошибок.

Дружественные страницы ошибок

Похоже, вы можете достичь своих целей с помощью хороших старомодных настроек web.config, которые были частью ASP.net в течение некоторого времени. Вы упомянули показ отладочной информации в dev и показ дружественных страниц в производстве. Для этого вы можете использовать пользовательский раздел ошибок web.config (установите CustomErrors = "Off", чтобы показать отладочную информацию). Я собираюсь предположить, что вы знакомы с атрибутом CustomErrors, если не читаете это:

http://msdn.microsoft.com/en-us/library/h0hfz6fc.aspx

Если вам нужна большая детализация контроля над отображаемыми представлениями ошибок, используйте MVC's HandleError Attribute. Таким образом, вы можете выбрать различные виды ошибок для каждого действия / контроллера.

http://weblogs.asp.net/scottgu/archive/2008/07/14/asp-net-mvc-preview-4-release-part-1.aspx

Регистрация исключений

Похоже, вы хотите одинаково реагировать на все ваши исключения («Регистрируйте ошибки и отправляйте их администратору по электронной почте»). В этом случае самый простой вариант - добавить код в

Application_Error (отправитель объекта, EventArgs e)

в вашем global.asax. Здесь вы можете перейти к выбранной вами системе ведения журналов.

Если вы хотите больше контроля над регистрацией / обработкой исключений, вы можете создать подкласс HandleErrorAttribute и переопределить

OnException(System.Web.Mvc.ExceptionContext filterContext)

это еще одно место, где вы можете перейти к выбранной вами системе ведения журналов.

https://stackoverflow.com/questions/183316/asp-net-mvc-handleerror

Это дает вам больше контроля, чем методика Application_Error, упомянутая выше.

В общем, MVC дает вам большую степень детализации контроля над ошибками. Если вам не нужен этот элемент управления, вы можете обратиться к ASP.net способам выполнения таких задач, как определение страниц ошибок в вашем файле web.config.

Никсона
источник
Большое спасибо за добавление ваших мыслей. Я думаю, что код состояния 302 - плохой выбор дизайна первоначальной командой ASP.NET. Я также расскажу об этом в своих ответах, для этого есть несколько вариантов. Похоже, некоторые в мире MVC полностью отказываются от customErrors и обрабатывают все это в приложении для лучшего повторного использования и большего контроля, как вы указали. Но я имел ограниченный успех в их реализации и добавлял много кода, который, казалось, был лучше испечен. Больше в моих ответах ниже.
Я предпочитаю переопределять метод OnException для регистрации, таким образом я знаю, что могу регистрировать все, даже ошибки, возникающие из-за вызова Ajax, который, как я обнаружил, не вызовет вашу ошибку Application_Error.
Алисия
@ Алисия полный пример кода?
Kiquenet