Быстрый ответ / TL; DR
Для ленивых людей там:
Install-Package MagicalUnicornMvcErrorToolkit -Version 1.0
Затем удалите эту строку из global.asax
GlobalFilters.Filters.Add(new HandleErrorAttribute());
И это только для IIS7 + и IIS Express.
Если вы используете Кассини .. ну .. эм .. эээ ... неловко ...
Долго объяснил ответ
Я знаю, что на это ответили. Но ответ ДЕЙСТВИТЕЛЬНО ПРОСТО (приветствует Дэвида Фаулера и Дамиана Эдвардса за то, что он действительно ответил на это).
Там нет необходимости делать что-либо на заказ .
За ASP.NET MVC3
все кусочки есть.
Шаг 1 -> Обновите ваш web.config в двух местах.
<system.web>
<customErrors mode="On" defaultRedirect="/ServerError">
<error statusCode="404" redirect="/NotFound" />
</customErrors>
а также
<system.webServer>
<httpErrors errorMode="Custom">
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="404" path="/NotFound" responseMode="ExecuteURL" />
<remove statusCode="500" subStatusCode="-1" />
<error statusCode="500" path="/ServerError" responseMode="ExecuteURL" />
</httpErrors>
...
<system.webServer>
...
</system.web>
Теперь внимательно обратите внимание на МАРШРУТЫ, которые я решил использовать. Вы можете использовать что угодно, но мои маршруты
/NotFound
<- для 404 не найдено, страница ошибки.
/ServerError
<- для любой другой ошибки, включите ошибки, которые происходят в моем коде. это 500 внутренняя ошибка сервера
Видите, как в первом разделе <system.web>
есть только одна пользовательская запись? statusCode="404"
Запись? Я перечислил только один код состояния, потому что все остальные ошибки, в том числе 500 Server Error
(т.е. те неприятные ошибки, которые возникают, когда в вашем коде возникает ошибка и происходит сбой запроса пользователя) ... все остальные ошибки обрабатываются настройкой defaultRedirect="/ServerError"
... которая говорит , если вы не нашли страницу 404, то пройдите по маршруту/ServerError
.
Хорошо. это вне пути .. теперь к моим маршрутам, перечисленным вglobal.asax
Шаг 2 - Создание маршрутов в Global.asax
Вот мой полный раздел маршрута ..
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{*favicon}", new {favicon = @"(.*/)?favicon.ico(/.*)?"});
routes.MapRoute(
"Error - 404",
"NotFound",
new { controller = "Error", action = "NotFound" }
);
routes.MapRoute(
"Error - 500",
"ServerError",
new { controller = "Error", action = "ServerError"}
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new {controller = "Home", action = "Index", id = UrlParameter.Optional}
);
}
Это перечисляет два маршрута игнорирования -> axd's
и favicons
(ooo! Бонус игнорировать маршрут, для вас!) Затем (и порядок здесь ИМПЕРАТИВНЫЙ ЗДЕСЬ), у меня есть два явных маршрута обработки ошибок ..., за которыми следуют любые другие маршруты. В этом случае по умолчанию. Конечно, у меня есть больше, но это специально для моего веб-сайта. Просто убедитесь, что маршруты ошибок находятся вверху списка. Порядок обязателен .
Наконец, пока мы находимся внутри нашего global.asax
файла, мы НЕ регистрируем глобально атрибут HandleError. Нет, нет, нет, сэр. Nadda. Нет. Nien. Negative. Noooooooooo ...
Удалить эту строку из global.asax
GlobalFilters.Filters.Add(new HandleErrorAttribute());
Шаг 3 - Создайте контроллер с методами действия
Теперь .. мы добавляем контроллер с двумя методами действия ...
public class ErrorController : Controller
{
public ActionResult NotFound()
{
Response.StatusCode = (int)HttpStatusCode.NotFound;
return View();
}
public ActionResult ServerError()
{
Response.StatusCode = (int)HttpStatusCode.InternalServerError;
// Todo: Pass the exception into the view model, which you can make.
// That's an exercise, dear reader, for -you-.
// In case u want to pass it to the view, if you're admin, etc.
// if (User.IsAdmin) // <-- I just made that up :) U get the idea...
// {
// var exception = Server.GetLastError();
// // etc..
// }
return View();
}
// Shhh .. secret test method .. ooOOooOooOOOooohhhhhhhh
public ActionResult ThrowError()
{
throw new NotImplementedException("Pew ^ Pew");
}
}
Хорошо, давайте проверим это. Прежде всего, здесь нет [HandleError]
атрибута. Почему? Потому что встроенный вASP.NET
фреймворк уже обрабатывает ошибки И мы указали все дерьмо, которое нам нужно сделать, чтобы обработать ошибку :) Именно в этом методе!
Далее у меня есть два метода действия. Ничего сложного там нет. Если вы хотите показать какую-либо информацию об исключении, то вы можете использовать, Server.GetLastError()
чтобы получить эту информацию.
Бонус WTF: Да, я сделал третий метод действия, чтобы проверить обработку ошибок.
Шаг 4 - Создание представлений
И наконец, создайте два представления. Поместите их в обычное место просмотра для этого контроллера.
Бонусные комментарии
- Вам не нужно
Application_Error(object sender, EventArgs e)
- Все вышеперечисленные шаги прекрасно работают с Elmah на 100% . Elmah Fraking Wroxs!
И это, друзья мои, должно быть так.
Теперь, поздравляю с чтением этого и единорог в качестве приза!