UPD : Here is the full solution for error handling
I've got plain vanilla MVC4 web-project. Nothing added, nothing deleted, just created a new project in Visual Studio.
In web.config
I've added custom error page handler:
<customErrors mode="On" defaultRedirect="~/Content/Error.htm" redirectMode="ResponseRewrite" />
and the ~/Content/Error.htm
file is:
<!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>
Whenever I get a 404 error on the site, Error.htm is served as plaintext in Firefox and Chrome:
Fiddler says that error page is served without content-type
header which leads browsers to render the page as plain-text:
Is there a way to force IIS server error pages with content-type
header??
ps the actual problem is in a complex MVC4 project, that has it's own error handling in Global.asax. But I found that some errors don't go through the ASP pipe and handled only by IIS. Like dot at the end of the url . Solution with < httpErrors /> does serve correct responses, but our custom error handling in Global.asax, Application_Error() is not getting called this way.
UPD Seems like I can't win this war. IE displays that html properly rendered, Firefox and Chrome shows as plain text. When I switch to plain-text, Firefox and IE shows white-space correctly, IE swallows white-space and tries to render html. If I try serve an image as error page, Firefox and Chrome show image. IE shows this: Facepalm!
对于错误页面使用.aspx而不是.htm(将htm重命名为aspx)。
<customErrors mode="On" defaultRedirect="~/Content/Error.aspx" redirectMode="ResponseRewrite" />
Apparently, <customErrors>
is a mess to get working. If you're determined to use it, Ben Foster has a great write-up on the subject: http://benfoster.io/blog/aspnet-mvc-custom-error-pages
If you want to use .cshtml pages, your best bet is probably to ditch <customErrors>
and handle errors in 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));
}
}
Of course, you would also need to add an ErrorController with the appropriate methods and .cshtml views.
public class ErrorController : Controller
{
public ActionResult Index()
{// your implementation
}
public ActionResult Unknown(Exception error)
{// your implementation
}
public ActionResult NotFound(Exception error)
{// your implementation
}
}
This is a known bug apparently and Microsoft's suggestion is in line with spiatrax's idea of renaming htm/html to aspx. In my case I also had to include
<% Response.StatusCode = 400 %>
in the .aspx page.
For more information: http://connect.microsoft.com/VisualStudio/feedback/details/507171/
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.