I'm trying to handle all application exceptions within global.asax for an MVC 3 project and whilst everything is working correctly within Cassini, as soon as I deploy to IIS 7.5, IIS starts taking control away from my application and handles many exceptions itself. This has the consequences of bypassing my custom logging and also returning ugly views.
I have a similar approach to Darin's answer to this question. Here's what I'm using at the moment.
protected void Application_Error(object sender, EventArgs e)
{
var app = (MvcApplication)sender;
var context = app.Context;
var exception = app.Server.GetLastError();
LogExceptionDetails(exception, Request.Url.PathAndQuery);
context.Response.Clear();
context.ClearError();
string redirectTo = "/error";
HttpException httpException = exception as HttpException;
if (httpException != null)
{
switch (httpException.GetHttpCode())
{
case 403:
redirectTo += "/forbidden";
break;
case 404:
redirectTo += "/notfound";
break;
}
}
Response.TrySkipIisCustomErrors = true;
// I should really change this so I can return a proper statusCode
Response.Redirect(redirectTo);
}
As an example, navigating to localhost/app_code
will return an ugly view and won't be logged. I have managed to at least make IIS return my custom views by using:
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="403" />
<error statusCode="403" path="/error/forbidden" responseMode="ExecuteURL" />
<remove statusCode="404" />
<error statusCode="404" path="/error/notfound" responseMode="ExecuteURL" />
</httpErrors>
That doesn't solve the logging problem though.
Other things I've tried include:
- Setting
existingResponse="PassThrough"
. - Using
<clear />
. - Various combinations of
httpErrors
with and withoutcustomErrors
. - Setting
<modules runAllManagedModulesForAllRequests="true" />
. Response.TrySkipIisCustomErrors = true;
Is there a way to handle this programmatically, whilst keeping things centralised in global.asax, rather than messing around with the web.config?