Я изо всех сил пытался реализовать обработку ошибок в моем приложении ASP.NET MVC 2. Я рассмотрел различные методы, но никто не работает должным образом. Я использую MVC2 и .NET 4.0 (начал проект до того, как был выпущен MVC3, мы обновим его после того, как мы выпустим наш начальный выпуск).
На этом этапе я буду рад правильно обрабатывать 404 и 500 ошибок - 403 (требуется авторизация), а также различные другие конкретные ответы. Прямо сейчас я либо получаю все 404, все 500, все 302 до 404, либо все 302 до 500.
Вот мои требования (которые должны быть близки к базовым требованиям HTTP):
-
Если ресурс не найден, бросьте 404 и отобразите страницу с 404-страницей с запрошенным URL-адресом. НЕ возвращайте промежуточный код ответа, например 302. В идеале сохраните запрошенный URL-адрес, а не покажите новый URL-адрес, например
/Error/NotFound
, но если последнее отобразится, убедитесь, что мы не вернули ответ перенаправления, чтобы получить его. -
Если произошла внутренняя ошибка сервера, введите 500 и отобразите 500-специфическую ошибку с некоторым указанием на то, что пошло не так. Опять же, не возвращайте промежуточный код ответа и в идеале не меняйте URL-адрес.
Вот что я считаю 404:
- Статический файл не найден:
/Content/non-existent-dir/non-existent-file.txt
- Контроллер не найден:
/non-existent-controller/Foo/666
- Контроллер найден, но действие не найдено:
/Home/non-existent-action/666
- Найден контроллер и действие, но действие не может найти запрошенный объект:
/Home/Login/non-existent-id
Вот то, что я считаю 500:
- Опубликовать отрицательное значение:
POST /User/New/new-user-name-too-long-for-db-column-constraint
- Проблема, не связанная с данными, как конечная точка веб-службы, не отвечающая
Некоторые из этих проблем должны быть идентифицированы конкретными контроллерами или моделями, а затем контроллеры должны выбросить соответствующее исключение HttpException. Остальное должно обрабатываться в более общем виде.
В случае 404 case # 2 я попытался использовать пользовательский ControllerFactory для выброса 404, если контроллер не может быть найден.
Для 404 случая №3 я попытался использовать настраиваемый базовый контроллер для переопределения HandleUnknownAction
и выбросить 404.
В обоих случаях я получаю 302 до 404. И я никогда не получаю 500 ошибок; если я модифицирую Web.config, чтобы поместить опечатку в конечную точку веб-службы, я все равно получаю 302, а 404 говорит, что URL (контроллер/действие), который использует веб-службу, не может быть найден.
Я также получаю запрошенный URL как параметр (n нежелательный) querystring: /Error/NotFound?aspxerrorpath=/Home/non-existent-action
Оба эти метода пришли из http://www.niksmit.com/wp/?p=17 (Как получить обычные страницы ошибок 404 (страница не найдена) с помощью ASP.Net MVC), на который указывает http://richarddingwall.name/2008/08/17/strategies-for-resource-based-404-errors-in-aspnet-mvc/
Если в Web.config у меня есть <customErrors mode="On" defaultRedirect="~/Error/Unknown" redirectMode="ResponseRedirect" />
, я получаю соответствующий код ответа, но мой контроллер ошибок никогда не вызывается. Вывод атрибута redirectMode
позволяет мне просматривать MVC-ошибки, но с промежуточным 302 и измененным URL-адресом и всегда одним и тем же контроллером (Unknown
= 500; если я изменю его на NotFound
, все будет выглядеть как 404).
Вот некоторые из других вещей, которые я прочитал и попытался реализовать:
- http://www.davidjuth.com/asp-net-mvc-error-handler.aspx
- http://sanjayuttam.com/wordpress/index.php/c-sharp/c-sharp-code-examples/error-handling-in-asp-net-mvc-1-part-2-of-2/
- http://blog.hebbink.com/post/2010/12/14/NET-custom-404-error-page-returns-302-for-http-status.aspx
- http://blog.dantup.com/2009/04/aspnet-mvc-handleerror-attribute-custom.html
- http://weblogs.asp.net/scottgu/archive/2008/07/14/asp-net-mvc-preview-4-release-part-1.aspx
.. вместе с кучей сообщений StackOverflow.
Мне кажется, что эта обработка ошибок довольно проста для веб-приложений, а в среде MVC должны быть настройки по умолчанию, которые делают это из коробки, и позволяют людям расширять ее, чтобы работать в противном случае. Возможно, они сделают это в будущем выпуске. В то же время, может ли кто-нибудь дать мне исчерпывающие сведения о том, как выполнять правильные ответы HTTP?