Устранение ошибок в ASP.NET MVC - это просто боль в заднице. Я перепробовал много предложений на этой странице и на других вопросах и сайтах, и ничего не работает хорошо. Одно из предложений заключалось в обработке ошибок на web.config внутри system.webserver , но только возвращает пустые страницы .
Моя цель при создании этого решения была:
- НЕ НАПРАВЛЕНО
- Возвращает PROPER STATUS CODES, а не 200 / Ok, как обработка ошибок по умолчанию
Вот мое решение.
1 . Добавьте следующее к system.web section
<system.web>
<customErrors mode="On" redirectMode="ResponseRewrite">
<error statusCode="404" redirect="~/Error/404.aspx" />
<error statusCode="500" redirect="~/Error/500.aspx" />
</customErrors>
<system.web>
Выше обрабатываются любые URL, не обработанные rout.config , и необработанные исключения, особенно те, которые встречаются в представлениях. Обратите внимание, что я использовал aspx , а не html . Поэтому я могу добавить код ответа к коду позади.
2 . Создайте папку с именем Ошибка (или что вы предпочитаете) в корне вашего проекта и добавьте две веб-формы. Ниже моя страница 404;
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="404.aspx.cs" Inherits="Myapp.Error._404" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title >Page Not found</title>
<link href="<%=ResolveUrl("~/Content/myapp.css")%>" rel="stylesheet" />
</head>
<body>
<div class="top-nav">
<a runat="server" class="company-logo" href="~/"></a>
</div>
<div>
<h1>404 - Page Not found</h1>
<p>The page you are looking for cannot be found.</p>
<hr />
<footer></footer>
</div>
</body>
</html>
И на коде позади я установил код ответа
protected void Page_Load(object sender, EventArgs e)
{
Response.StatusCode = 404;
}
Сделайте то же самое для страницы 500
3 . Для обработки ошибок в контроллерах. Есть много способов сделать это. Это то, что сработало для меня. Все мои контроллеры наследуются от базового контроллера. В базовом контроллере у меня есть следующие методы
protected ActionResult ShowNotFound()
{
return ShowNotFound("Page not found....");
}
protected ActionResult ShowNotFound(string message)
{
return ShowCustomError(HttpStatusCode.NotFound, message);
}
protected ActionResult ShowServerError()
{
return ShowServerError("Application error....");
}
protected ActionResult ShowServerError(string message)
{
return ShowCustomError(HttpStatusCode.InternalServerError, message);
}
protected ActionResult ShowNotAuthorized()
{
return ShowNotAuthorized("You are not allowed ....");
}
protected ActionResult ShowNotAuthorized(string message)
{
return ShowCustomError(HttpStatusCode.Forbidden, message);
}
protected ActionResult ShowCustomError(HttpStatusCode statusCode, string message)
{
Response.StatusCode = (int)statusCode;
string title = "";
switch (statusCode)
{
case HttpStatusCode.NotFound:
title = "404 - Not found";
break;
case HttpStatusCode.Forbidden:
title = "403 - Access Denied";
break;
default:
title = "500 - Application Error";
break;
}
ViewBag.Title = title;
ViewBag.Message = message;
return View("CustomError");
}
4 . Добавьте файл CustomError.cshtml в папку Shared views. Ниже мое;
<h1>@ViewBag.Title</h1>
<br />
<p>@ViewBag.Message</p>
Теперь в вашем контроллере приложения вы можете сделать что-то вроде этого;
public class WidgetsController : ControllerBase
{
[HttpGet]
public ActionResult Edit(int id)
{
Try
{
var widget = db.getWidgetById(id);
if(widget == null)
return ShowNotFound();
//or return ShowNotFound("Invalid widget!");
return View(widget);
}
catch(Exception ex)
{
//log error
logger.Error(ex)
return ShowServerError();
}
}
}
Теперь для предостережения .
Он не будет обрабатывать статические ошибки файла. Поэтому, если у вас есть маршрут, такой как example.com / widgets , и пользователь меняет его на example.com / widgets.html , он получит страницу ошибки IIS по умолчанию, поэтому для обработки ошибок уровня IIS другим способом.