I have an MVC3 website and I'm trying to get the 404 error pages to show correctly. I've got it all set up that it
- does not redirect the URL,
- returns an actual 404 error status in the header,
- logs the URL,
- is a custom page I've created,
- and is an actual action/controller page instead of a .aspx/.html page.
Debugging in Visual Studio, it works perfectly. When I post it to my test or production environment, it does not work and returns a generic file not found with the 404 status in the header.
The error page isn't the default 404 error ( this nor this ) but seems to be global custom on the server itself (the server hosts several sites, all 404s show the same simple line page). The error page on the server actually shows a 500 error page. Also, I've set Response.TrySkipIisCustomErrors = true to try to bypass it, but that doesn't work.
On the production and test servers, it is being logged correctly and if I have it not return the 404 status code, it displays my error page. So with that, I'm pretty sure the action/view are working, but it's somehow with the server. It's running ASP.NET 4 and IIS 7.
Any suggestions of what/where to investigate to fix this?
.
Resources of code I've based my solution thus far on
How can I properly handle 404 in ASP.NET MVC?
This is the base for what I'm doing by capturing the exception in Application_Error; I'm still a little wary of it because it could easily lead to a loop, so I've try/catched everything to protect against that (error happens within catching another error)
Code in global.asax
protected void Application_Error(object sender, EventArgs e)
{
try
{
Exception exception = Server.GetLastError();
Response.Clear();
HttpException httpException = exception as HttpException;
RouteData routeData = new RouteData();
routeData.Values.Add("controller", "Error");
if (httpException == null)
{
routeData.Values.Add("action", "NotFound");
}
else
{
switch (httpException.GetHttpCode())
{
case 404:
// Page not found.
routeData.Values.Add("action", "NotFound");
break;
case 500:
// Server error.
routeData.Values.Add("action", "ServerError");
break;
default:
routeData.Values.Add("action", "General");
break;
}
}
routeData.Values.Add("error", exception);
Server.ClearError();
Response.TrySkipIisCustomErrors = true;
IController errorController = new ErrorController();
errorController.Execute(new RequestContext(
new HttpContextWrapper(Context), routeData));
}
catch
{
//
}
}
Code in Error Controller
public ActionResult NotFound()
{
try
{
Response.StatusCode = (int)HttpStatusCode.NotFound;
Response.TrySkipIisCustomErrors = true;
}
catch
{}
return View();
}