Application_Error not firing when customerrors = “

2019-01-04 16:54发布

I have code in the global.asax file's Application_Error event which executes when an error occurs and emails details of the error to myself.

void Application_Error(object sender, EventArgs e)
{
    var error = Server.GetLastError();

    if (error.Message != "Not Found")
    {
        // Send email here...
    }

}

This works fine when I'm running it in Visual Studio, however when I publish to our live server the Application_Error event does not fire.

After some testing I can get the Application_Error firing when I set customErrors="Off", however setting it back to customErrors="On" stops the event from firing again.

Can anyone suggest why Application_Error would not be firing when customErrors are enabled in the web.config?

9条回答
女痞
2楼-- · 2019-01-04 17:13

I found an article which describes a much cleaner way of making custom error pages in an MVC3 web app which does not prevent the ability to log the exceptions.

The solution is to use the <httpErrors> element of the <system.webServer> section.

I configured my Web.config like so...

<httpErrors errorMode="DetailedLocalOnly" existingResponse="Replace">
  <remove statusCode="404" subStatusCode="-1" />
  <remove statusCode="500" subStatusCode="-1" />
  <error statusCode="404" path="/Error/NotFound" responseMode="ExecuteURL" />
  <error statusCode="500" path="/Error" responseMode="ExecuteURL" />
</httpErrors>

I also configured customErrors to have mode="Off" (as suggested by the article).

That makes the responses overriden by an ErrorController's actions. Here is that controller:

public class ErrorController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult NotFound()
    {
        return View();
    }
}

The views are very straight forward, I just used standard Razor syntax to create the pages.

That alone should be enough for you to use custom error pages with MVC.

I also needed logging of Exceptions so I stole the Mark's solution of using a custom ExceptionFilter...

public class ExceptionPublisherExceptionFilter : IExceptionFilter
{
    public void OnException(ExceptionContext exceptionContext)
    {
        var exception = exceptionContext.Exception;
        var request = exceptionContext.HttpContext.Request;
        // log stuff
    }
}

The last thing you need to so is register the Exception Filter in your Global.asax.cs file:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new ExceptionPublisherExceptionFilter());
    filters.Add(new HandleErrorAttribute());
}

This feels like a much cleaner solution than my previous answer and works just as well as far as I can tell. I like it especially because it didn't feel like I was fighting against the MVC framework; this solution actually leverages it!

查看更多
劫难
3楼-- · 2019-01-04 17:19

In case of ASP.NET MVC5 use

public class ExceptionPublisherExceptionFilter : IExceptionFilter
    {
        private static Logger _logger = LogManager.GetCurrentClassLogger();
        public void OnException(ExceptionContext exceptionContext)
        {
            var exception = exceptionContext.Exception;
            var request = exceptionContext.HttpContext.Request;
            // HttpException httpException = exception as HttpException;
            // Log this exception with your logger
            _logger.Error(exception.Message);
        }
    }

You can find it in FilterConfig.cs of App_Start folder.

查看更多
Evening l夕情丶
4楼-- · 2019-01-04 17:27

This blog entry helped me:

http://asp-net.vexedlogic.com/2011/04/23/asp-net-maximum-request-length-exceeded/

If you're using IIS 7.0 or higher, you can alter your Web.config file to handle requests that are too large. There are some caveats, but here is an example:

<system.webServer>
  <security>
    <requestFiltering>
      <requestLimits maxAllowedContentLength="1048576" />
    </requestFiltering>
  </security>
  <httpErrors errorMode="Custom" existingResponse="Replace">
    <remove statusCode="404" subStatusCode="13" />
    <error statusCode="404" subStatusCode="13" prefixLanguageFilePath="" path="/UploadTooLarge.htm" responseMode="Redirect" />
  </httpErrors>
</system.webServer>

There are additional details about these config file elements here:

http://www.iis.net/ConfigReference/system.webServer/security/requestFiltering/requestLimits

Status code 404.13 is defined as "Content Length Too Large". One important thing to note is that the maxAllowedContentLength is specified in bytes. This is different from the maxRequestLength setting you find in the <system.web> section, which is specified in kilobytes.

<system.web>
  <httpRuntime maxRequestLength="10240" />
</system.web>

Also note that the path attribute must be an absolute path when the responseMode is Redirect, so prepend the virtual directory name, if relevant. Jesse Webb's informative answers show how to do this with responseMode="ExecuteURL", and I would think that approach would work well, too.

This approach does not work if you're developing using the Visual Studio Development Server (Cassini, the Web server integrated into Visual Studio). I'm assuming it would work in IIS Express, but I haven't tested that.

查看更多
登录 后发表回答