My question is closely related to this question.
Here is a quick synopsis: My app is running in Classic Mode. I have the following code in Global.asax
protected void Application_Error(Object sender, EventArgs e)
{
// ... boring stuff...
HttpContext.Current.Server.Transfer("~/MyErrorPage.aspx", true);
}
Everything works OK (i.e. I see MyErrorPage.aspx) when an error occurs if
<httpErrors errorMode="Detailed" />
but when errorMode="Custom"
(or errorMode="DetailedLocalOnly"
and the request is from a remote machine), I see the IIS custom error page followed by my error page (MyErrorPage.aspx).
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!-- The contents of the default 500 page as configured in IIS
Which for me is the default %SystemDrive%\inetpub\custerr\<LANGUAGE-TAG>\500.htm
-->
</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<!-- The contents of MyErrorPage.aspx -->
</html>
If I remove the default 500 error page from the IIS error pages section then I get the following output (note that I get "The page cannot be displayed..." instead of the custom 500 page)
The page cannot be displayed because an internal server error has occurred.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<!-- The contents of MyErrorPage.aspx -->
</html>
If I step through the code using the debugger, then I see that the IIS 500 page gets flushed to the client when I step over the Server.Transfer
statement.
My error page then gets sent to the browser after the normal page lifecycle of the MyErrorPage.aspx (as you would expect).
I have tried (in desperation) clearing the content of the response (HttpContext.Current.Response.Clear()
) prior to the Server.Transfer but that has no effect.
I have also tried calling Server.ClearError()
prior to the transfer but that has no effect either.
Now as per the linked question, the "fix" is to set errormode="Detailed"
but I do not want to see the detailed error pages for errors that are not handled in ASP.Net - for example I would prefer to see the IIS custom 404 page instead of the detailed page if I enter the url myApp/DoesNotExist.html
. [Some of our customers absolutely insist that users never see the detailed error page because it is deemed a potential security weakness.]
Another "fix" is to redirect instead doing a server transfer but I would prefer to do a transfer if possible: doing a transfer means that the browser's URL is unchanged, meaning that, for example, if the error occurred because the app.was just starting up, they can hit F5 to retry the request. Redirecting obviously changes the browser's address to the error page.
Does anyone have an explaination as to why I am seeing this behaviour? Does anyone have a solution?
Thanks in advance.
Edit
I have knocked together a little app that demonstrates the behaviour :
http://rapidshare.com/files/427244682/Err.zip
[Make sure that the app is running in Classic mode.]
If you click on a link that has both transfer and setstatus args set then you see the problem. BANG