ASP.NET Application_Error being invoked twice
I use Application_Error
to handle errors in an ASP.NET MVC 3 application. Today I noticed that for one particular error case, this method is called twice: When requesting a resouce with a leading underscore, as e.g. _ViewStart.cshtml
.
The implementation of Application_Error
consumes the last server error:
var exception = server.GetLastError();
server.ClearError();
...
Therefore, when it's called for the second time, GetLastError
returns null
. When it's called for the first time, it sets a corresponding status code and content on the response object. The second invocation then caused al开发者_如何学Cl these settings to be overwritten. To work around this issue, I now check for a null pointer:
if (exception == null) return;
This way, it works perfectly fine: The first run of the method replaces the response by an error page and sets the status code. The second run does nothing. Then the response is sent to the client who gets the correct status code and error page.
But this line of code looks like dirty to me. I would prefer to understand what is going on rather than having the error handler quit silently when in fact something must have gone wrong.
Please note: It seems like no exception is thrown anywhere during the first run of the error handling. Otherwise I could understand it. But when debugging it line by line, the whole Application_Error
method is processed, including an MVC call to a controller and the rendering of the views. In fact, after following gordonml's comment and checking the "Break when CLR exception is thrown" flag, Visual Studio did never break, not even before the first invocation of Application_Error.
The exact same thing happened to me.
My solution was the following ( I don't like it, but I like it better than if(exception == null) return;
)
In the case that the exception is thrown within an AJAX call to the server, I just removed the Response.StatusCode = (int)401
.
I had that in the Global.asax.cs
because sometimes, the API access token expired earlier than the http session. If I set Response.StatusCode = 500, the Application_Error
does not fire twice.
There are two possibilities in your Web.config to define custom errors. Make sure only one of them is present, otherwise the corresponding erros are called twice.
<httpErrors errorMode="Custom" defaultResponseMode="ExecuteURL">
<error statusCode="404" path="/Error/NotFound" responseMode="ExecuteURL" />
...
</httpErrors>
<customErrors mode="On">
<error redirect="~/Error/NotFound" statusCode="404" />
...
</customErrors>
精彩评论