Ответ 1
Используйте .aspx вместо .htm для страниц ошибок (переименуйте htm в aspx).
<customErrors mode="On" defaultRedirect="~/Content/Error.aspx" redirectMode="ResponseRewrite" />
UPD: вот полное решение для обработки ошибок
У меня есть простой веб-проект vanilla MVC4. Ничего не добавлено, ничего не удалено, просто создал новый проект в Visual Studio.
В web.config
Я добавил пользовательский обработчик страницы ошибок:
<customErrors mode="On" defaultRedirect="~/Content/Error.htm" redirectMode="ResponseRewrite" />
а файл ~/Content/Error.htm
:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>OOPS! Error Occurred. Sorry about this.</title>
</head>
<body>
<h2>OOPS! Error Occurred</h2>
</body>
</html>
Всякий раз, когда я получаю ошибку 404 на сайте, Error.htm используется как открытый текст в Firefox и Chrome:
Fiddler говорит, что страница с ошибкой подается без заголовка content-type
, который заставляет браузеры отображать страницу как обычный текст:
Есть ли способ заставить страницы ошибок сервера IIS с заголовком content-type
p.s. фактическая проблема заключается в сложном проекте MVC4, который имеет собственную обработку ошибок в Global.asax. Но я обнаружил, что некоторые ошибки не проходят через ASP-канал и обрабатываются только IIS. Как точка в конце URL. Решение с < httpErrors/" > выполняет корректные ответы, но наша настраиваемая обработка ошибок в Global.asax, Application_Error() не вызвана таким образом.
UPD Кажется, я не могу победить в этой войне. IE показывает, что html правильно отображается, Firefox и Chrome отображаются как обычный текст. Когда я переключаюсь на обычный текст, Firefox и IE корректно показывают пустое пространство, IE поглощает пустое пространство и пытается отобразить html. Если я попробую показать изображение как страницу с ошибкой, Firefox и Chrome покажут изображение. IE показывает это:
Facepalm!
Используйте .aspx вместо .htm для страниц ошибок (переименуйте htm в aspx).
<customErrors mode="On" defaultRedirect="~/Content/Error.aspx" redirectMode="ResponseRewrite" />
По-видимому, <customErrors>
- беспорядок, чтобы работать. Если вы полны решимости использовать его, Бен Фостер отлично разбирается в этой теме: http://benfoster.io/blog/aspnet-mvc-custom-error-pages
Если вы хотите использовать страницы .cshtml, лучший выбор - это, возможно, вырезать <customErrors>
и обрабатывать ошибки в Global.asax.cs:
protected void Application_Error(object sender, EventArgs e)
{
var exception = Server.GetLastError();
if (exception != null)
{
Response.Clear();
HttpException httpException = exception as HttpException;
RouteData routeData = new RouteData();
routeData.Values.Add("controller", "Error");
if (httpException == null)
{
routeData.Values.Add("action", "Unknown");
}
else
{
switch (httpException.GetHttpCode())
{
case 404: // Page not found.
routeData.Values.Add("action", "NotFound");
break;
default:
routeData.Values.Add("action", "Unknown");
break;
}
}
// Pass exception details to the target error View.
routeData.Values.Add("Error", exception);
// Clear the error on server.
Server.ClearError();
// Avoid IIS7 getting in the middle
Response.TrySkipIisCustomErrors = true;
// Ensure content-type header is present
Response.Headers.Add("Content-Type", "text/html");
// Call target Controller and pass the routeData.
IController errorController = new ErrorController();
errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
}
}
Конечно, вам также необходимо добавить ErrorController с соответствующими методами и представлениями .cshtml.
public class ErrorController : Controller
{
public ActionResult Index()
{// your implementation
}
public ActionResult Unknown(Exception error)
{// your implementation
}
public ActionResult NotFound(Exception error)
{// your implementation
}
}
Это известная ошибка, очевидно, и предложение Microsoft соответствует идее spiatrax о переименовании htm/html в aspx. В моем случае я также должен был включить
<% Response.StatusCode = 400 %>
на странице .aspx.
Для дополнительной информации: http://connect.microsoft.com/VisualStudio/feedback/details/507171/
Я добавил заголовок типа контента в пользовательский заголовок в разделе system.webServer/httpprotocol
, и это исправило его.
<customHeaders><remove name="Content-Type" /><add name="ContentType"value="text/html" /></customHeaders>