Які остаточні вказівки щодо користувацького поводження з помилками в ASP.NET MVC 3?


44

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

Ось мої цілі:

Для помилок / винятків сервера:

  1. Відображати інформацію про налагодження у програмі Dev
  2. Відобразити дружню сторінку помилок у виробництві
  3. Помилки в журналі та надсилайте їх по електронній пошті адміністратору
  4. Повернути 500 код коду HTTP

Для 404 помилок не знайдено:

  1. Відобразити дружню сторінку помилки
  2. Помилки в журналі та надсилайте їх по електронній пошті адміністратору
  3. Повернути 404 код коду HTTP

Чи є спосіб досягти цих цілей за допомогою ASP.NET MVC?


2
Я хотів би перенести це запитання НАЗАД на ТАК, щоб отримати більше відповідей. Я шукаю кодовані відповіді.
Шон Мклін

@Shawn Це навряд чи станеться. Питання тут більше на тему, ніж на SO, і він має прийняту відповідь. Зазвичай питання з технічних причин повторно не мігруються. Якщо вам потрібна допомога в кодуванні конкретного підходу до вирішення помилок, будь ласка, відкрийте нове запитання на StackOverflow. В іншому випадку "кодовані відповіді" можуть бути занадто широкими критеріями, щоб бути корисними або відповідатими. І останнє, але не менш важливе, найкращий спосіб привернути увагу модератора до питання - позначити його. Ваш коментар тут, ймовірно, залишився б непоміченим, якби він не вимкнув авто-прапор, натиснувши кількість коментарів більше 20.
Адам Лір

Тут раніше було десь 10 коментарів, куди вони все пішли?
RyanW

Я знайшов рішення, яке відповідає вашим цілям. У мене це ще одна відповідь на ТАК: stackoverflow.com/questions/6508415/…
Джессі Вебб

1
@AnnaLear Я погоджуюся з Шоном. Я знайшов цю сторінку лише через Google. Зауважте, що майже всі відповіді нижче містять посилання НАЗАД на переповнення стека. Мені, що говорить багато, тим, що воно мало бути залишене там в першу чергу.
Ребекка

Відповіді:


23

Я поділюсь тим, як я закінчила це робити, що було частиною оригінального питання.

По-перше, проблеми, з якими я стикався:

  1. Якщо користувальницькі користувачі користуються користувальницькими помилками (тобто у виробництві), глобальний HandleErrorатрибут поглинає винятки та надає ваше уявлення про помилку, але тоді ви не можете ввійти в нього за допомогою інструменту addon, такого як 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.StatusCode404, а в Error.aspx - код 500.

Результати:

Цілі для обох були досягнуті за допомогою журналів Elmah, дружньої сторінки помилок та коду статусу з одним рядком коду на кодах. Ми не робимо це "MVC Way", як це було зроблено в попередньому рішенні, але я добре з цим, якщо це два рядки коду.


5

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

ПРИМІТКА. Ви не можете відображати дружню сторінку помилки та повертати HTTP 404 або 500, як пропонує ваше запитання. Коли ви повернете дружню сторінку помилки, HTTP-код, повернутий у ваш браузер, буде 302. Це перенаправлення на дружню сторінку помилки.

Дружні сторінки помилок

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

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

Якщо вам потрібен більш детальний контроль над тим, які вікна помилок відображаються, то використовуйте атрибут HandleError від MVC. Таким чином, ви можете вибрати різні види помилок для кожної дії / контролера.

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 способів вчинити такі дії, як визначення сторінок помилок на веб-сайті.


Дуже дякую за додавання ваших думок. Я думаю, що код статусу 302 - це поганий вибір дизайну оригінальною командою ASP.NET. У цьому я відповім і на свої відповіді. Є кілька варіантів для цього. Здається, деякі в світі MVC повністю відмовляються від customErrors і обробляють все це в додатку для кращого використання та більшого контролю, як ви вказуєте. Але я мав обмежений успіх у впровадженні цих програм і додав багато коду, який, здавалося, краще запекло. Більше у моїх відповідях нижче.

Я вважаю за краще замінити метод OnException для ведення журналів, таким чином я знаю, що я можу записати все, навіть помилка, що виникає при виклику Ajax, і я виявив, що не запустить ваш Application_Error.
Алісія

@Alicaa повний зразок коду?
Кікенет
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.