views:

330

answers:

1

Hi,

First of all, quickly what exactly I want to achieve: translate particular exception into the HTTP 404 so the ASP.NET can handle it further.

I am handling exceptions in the ASP.NET (MVC2) this way:

    protected void Application_Error(object sender, EventArgs e) {
        var err = Server.GetLastError();
        if (err == null)
            return;
        err = err.GetBaseException();

        var noObject = err as ObjectNotFoundException;
        if (noObject != null)
            HandleObjectNotFound();

        var handled = noObject != null;
        if (!handled)
            Logger.Fatal("Unhandled exception has occured in application.", err);
    }

    private void HandleObjectNotFound() {
        Server.ClearError();
        Response.Clear();
        // new HttpExcepton(404, "Not Found"); // Throw or not to throw?
        Response.StatusCode = 404;
        Response.StatusDescription = "Not Found";
        Response.StatusDescription = "Not Found";
        Response.Write("The whole HTML body explaining whata 404 is??");
    }

The problem is that I cannot configure default customErrors to work with it. When it is on then it never redirects to the page specified in customErrors: <error statusCode="404" redirect="404.html"/>.

I also tried to raise new HttpExcepton(404, "Not Found") from the handler but then the response code is 200 which I don't understand why.

So the questions are:

  1. What is the proper way of translating AnException into HTTP 404 response?
  2. How does customErrors section work when handling exceptions in Application_Error?
  3. Why throwing HttpException(404) renders (blank) page with success (200) status?

Thanks,
Dmitriy.

A: 

Hi

In a few words, you if you manually set HTTP status in Application_Error, you loose possibility to use customErrors section handler, since you call Server.ClearError().

Handle the exception before Application_Error or derive the exception from HttpException.

  • What is the proper way of translating AnException into HTTP 404 response?

It's better to handle exceptions in Controller. You can introduce base class controller and handle most of exceptions in custom HandleError attribute. You can throw HttpException their and it will be properly handled by customErrors section handler.

You can also derive your ObjectNotFoundException exception from HttpException(404)

Application_Error is the last chance to handle an exception. You have only Response API to handle it. You can manually set status code and write to response or manually trigger redirect to custom error page or call Server.TransferRequest() to existing html or aspx file (not to the controller action). In current asp.net version, you cannot set or change Server.GetLastError in Application_Error method only retrieve or clear it.

  • How does customErrors section work when handling exceptions in Application_Error?

By calling Server.ClearError() you also clean current request error therefore it is not handled by customErrors section handler

  • Why throwing HttpException(404) renders (blank) page with success (200) status?

You should no throw any exception in Application_Error method. Exception means that your error handling failed.

Andrej Golcov
`It's better to handle exceptions in Controller` - maybe, but it won't catch Non-Mvc exception, which I do need.`derive your ObjectNotFoundException exception from HttpException` - not possible, it is the exception from the Data layer and has nothing to do with HTTP.`You can manually set status code and write to response` - in this case `customErrors` configuration will not be kicked in.`manually trigger redirect to custom error page` - why in hell then do we have `*custom*Errors` section.Such a simple thing, but so many obstacles, - just kick-in customError handler on given exception.
Dmytrii Nagirniak
Dmitriy, I agree with you that it will be fine to change Server.GetLastError in Application_Error. But current ASP.Net API does not allow to do it. "but it won't catch Non-Mvc exception, which I do need." - You should able to catch all exceptions on controller level by using standard or implementing custom HandleError attribute. Try to avoid throwing an exception during view rendering.If you get the exception during view rendering, may be this article can be useful for you: http://stackoverflow.com/questions/1074540/how-to-catch-exception-of-mvc-view
Andrej Golcov
Andrej, I cannot catch all the exceptions on the controller level as there are regular WebForms pages as other non MVC parts in the application, so the only one place to handle all errors is the global application object. Which is fine, I just cannot figure out how to "return" 404 from there, so that it will be handled by `customErrors`.
Dmytrii Nagirniak
Dmitriy, you can't do that in Application_Error. But you can easily implement similar functionality to customError section handler. Check this link: http://stackoverflow.com/questions/1171035/asp-net-mvc-custom-error-handling-application-error-global-asax
Andrej Golcov