Implementing a custom error in global.asax

2020-03-26 08:33发布

问题:

In my global.asax file, I have the following code:

void Application_Error(object sender, EventArgs e)
{
    Exception TheError = Server.GetLastError();

    if (TheError is HttpException && ((HttpException)TheError).GetHttpCode() == 404)
    {
        Response.Redirect("~/404.aspx");
    }
    else
    {
        Response.Redirect("~/500.aspx");
    }
}

When I navigate to an non-existing page, I get the generic error page. I don't want anything pertaining to custom error in the web.config because my plan is to add code to the global.asax file to log the exceptions. Is there a way to handle custom error with just the global.asax file?

回答1:

EDIT:

The answer is not obvious, but this seems to explain it: http://www.asp.net/web-forms/tutorials/deployment/deploying-web-site-projects/displaying-a-custom-error-page-cs

If you scroll down a ways, you'll find this lovely tidbit:

Note: The custom error page is only displayed when a request is made to a resource handled by the ASP.NET engine. As we discussed in the Core Differences Between IIS and the ASP.NET Development Server tutorial , the web server may handle certain requests itself. By default, the IIS web server processes requests for static content like images and HTML files without invoking the ASP.NET engine. Consequently, if the user requests a non-existent image file they will get back IIS's default 404 error message rather than ASP.NET's configured error page.

I've emphasized the first line. I tested this out in the default template, and sure enough, this URL:

http://localhost:49320/fkljflkfjelk

gets you the default IIS page, whereas simply appending a .aspx makes the Application_Error kick in. So, it sounds like you need to enable customErrors/httpErrors if you want to have all errors handled.

For IIS <= 6, add to <system.web>:

<customErrors mode="On" redirectMode="ResponseRewrite">
  <error statusCode="404" redirect="/404.aspx"/>
  <error statusCode="500" redirect="/500.aspx"/>
</customErrors>

For IIS7+, add to <system.webServer>:

<httpErrors errorMode="Custom">
  <remove statusCode="404"/>
  <error statusCode="404" path="/404.aspx" responseMode="ExecuteURL"/>
  <remove statusCode="500"/>
  <error statusCode="500" path="/500.aspx" responseMode="ExecuteURL"/>
</httpErrors>

I'll leave the original answer in case someone finds it useful.


I believe you need to clear the existing error code from the response, otherwise IIS ignores your redirect in favor of handling the error. There's also a Boolean flag, TrySkipIisCustomErrors, you can set for newer versions of IIS (7+).

So, something like this:

void Application_Error(object sender, EventArgs e)
{
    Exception TheError = Server.GetLastError();
    Server.ClearError();

    // Avoid IIS7 getting in the middle
    Response.TrySkipIisCustomErrors = true;

    if (TheError is HttpException && ((HttpException)TheError).GetHttpCode() == 404)
    {
        Response.Redirect("~/404.aspx");
    }
    else
    {
        Response.Redirect("~/500.aspx");
    }
}


回答2:

Looks like IIS is looking for a page and did not find it.

Make sure:

  1. 404.aspx is created
  2. customErrors tag from web.config is not present.


标签: c# asp.net