views:

299

answers:

1

Here's my Application_OnError event sink in global.asax.vb:

    Sub Application_OnError(ByVal sender As Object, ByVal e As EventArgs)

    Dim innerMostException As Exception = getInnerMostException(Me.Context.Error)

    If TypeOf innerMostException Is AccessDeniedException Then

        Security.LogAccessDeniedOccurrence(DirectCast(innerMostException, AccessDeniedException))

        Dim fourOhThree As Integer = DirectCast(HttpStatusCode.Forbidden, Integer)

        Throw New HttpException(fourOhThree, innerMostException.Message, innerMostException)

    End If

End Sub

You'll see that if we've got an innermost Exception of type AccessDeniedException we throw a new HTTPExcpetion with a status code of 403 AKA 'forbidden'

Here's the relevant web.config entry:

    <customErrors defaultRedirect="~/Application/ServerError.aspx" mode="On">
      <error statusCode="403" redirect="~/Secure/AccessDenied.aspx" />
    </customErrors>    

So what we're expecting is a redirect to the AccessDenied.aspx page. What we get is a redirect to the ServerError.aspx page.

We've also tried this:

    Sub Application_OnError(ByVal sender As Object, ByVal e As EventArgs)

    Dim innerMostException As Exception = getInnerMostException(Me.Context.Error)

    If TypeOf innerMostException Is AccessDeniedException Then

        Security.LogAccessDeniedOccurrence(DirectCast(innerMostException, AccessDeniedException))

        Context.Response.StatusCode = DirectCast(HttpStatusCode.Forbidden, Integer)

    End If

End Sub

Which unsuprisingly doesn't work either.

Any ideas what we're doing wrong?

A: 

Application_Error is intended to catch errors that aren't handled by your application. When it fires, an error has already happened and everything is about that error. If you throw an error from within Application_Error you are actually saying "there's an error with my error handler". Instead just Server.Transfer to the appropriate page. If you want to keep all of your redirection logic in web.config you can see this article about how to parse the customErrors section to figure out where to redirect to.

All this said, and I haven't tried this, but can you try calling Server.ClearError():

            Dim Ex = Server.GetLastError()
            Server.ClearError()
            Throw New HttpException(System.Net.HttpStatusCode.Forbidden, Nothing, Ex)

I don't think it will work because of what I said above but its worth a try.

Chris Haas
Yeah, I guess I got a bit tunnel-visioned about using the redirection via the custom errors section in web.config and dismissed just doing a server.transfer. Thanks for the help.