I've been working on some internal applications for a while, and I can't quite get the error-handling to work correctly. When a user hits a controller that exists it all works normally. If the user tries to go to a URL of a controller that doesn't exist the error handling all works as normal, but when the view is served it displays as HTML in the browser. What am I doing wrong?
I grab all Application Errors in the Global.asax
and then forward them to an Error controller.
private void Application_Error(object sender, EventArgs e)
{
var exception = Server.GetLastError();
#if !DEBUG
exception.AddExceptionDataValue("User", User?.Identity?.Name);
exception.HandleException();
#endif
var httpException = exception as HttpException;
if (httpException != null)
{
Response.StatusCode = httpException.GetHttpCode();
}
Server.ClearError();
Response.TrySkipIisCustomErrors = true;
IController controller = new ErrorController();
var routeData = new RouteData();
routeData.Values.Add("controller", "Error");
routeData.Values.Add("action", "Index");
routeData.Values.Add("message", exception == null ? "Details not available." : exception.Message);
var rc = new RequestContext(new HttpContextWrapper(Context), routeData);
controller.Execute(rc);
}
This results in passing the error message to my Error controller on EVERY error. The only difference is what is displayed to the user.
EDIT: I've found this ONLY happens with IIS Express. When this runs on a real server with IIS all error pages are rendered like in the first example. IIS Express just displays raw HTML to the user for some reason. I can only get around this by using the web.config <httpErrors>
section to handle each status code and forward to a controller action, but that seems unnecessary since my Global.asax will handle it in production without an issue.
Example of an error generated inside an existing controller (even if the action doesn't exist):
Example of an error generated by trying to access a non-existent controller (it's the entire document including the error message):