Where do I catch and handle maxAllowedContentLength exceeded in IIS7?

亡梦爱人 提交于 2019-11-28 07:39:19
sunflowerpower

After looking at the ASP.NET Application Life Cycle Overview for IIS 7.0 and doing my own experimentation, I'm assuming that the request validation is done internally by IIS before any of the events are raised.

It looks like only LogRequest, PostLogRequest, EndRequest, PreSendRequestContent, and PreSendRequestHeaders are raised after the internal validation with this error.

I've decided to attach an event handler to the HttpApplication.EndRequest event in my custom error handler and check for the 404.13 status code on POST and handle as I need it to be handled, which in my case is to redirect to the calling page which will check Server.GetLastError() and display a friendly error to the end user.

private void application_EndRequest(object sender, EventArgs e)
{
    HttpRequest request = HttpContext.Current.Request;
    HttpResponse response = HttpContext.Current.Response;

    if ((request.HttpMethod == "POST") &&
        (response.StatusCode == 404 && response.SubStatusCode == 13))
    {
        // Clear the response header but do not clear errors and
        // transfer back to requesting page to handle error
        response.ClearHeaders();
        HttpContext.Current.Server.Transfer(
            request.AppRelativeCurrentExecutionFilePath);
    }
}

I'd welcome feedback on this approach and alternatives.

Triynko

The simplest method is to handle it in the OnError method of page itself.

I think this works only in .NET 4.0, since the WebEventCode property is documented as NEW in .NET 4.0.

protected override void OnError(EventArgs e)
{
    Exception err = Server.GetLastError();
    if (err is HttpException)
    {
        if ((err as HttpException).WebEventCode == 3004)
        {
            Context.Items["error"] = "File exceeded maximum allowed length.";
            Server.Transfer( Context.Request.Url.LocalPath );
            return;
        }
    }
    base.OnError(e);
}

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    if (!IsPostBack)
    {
        string error = Context.Items["error"] as string;
        if (!string.IsNullOrEmpty( error ))
            showErrorMessage( error );
    }
}

What I did was:

  • get the last error with Server.GetLastError
  • check that it's a "Maximum request length exceeded." error (WebEventCode == 3004).
  • added a value to Context.Items collections to flag the request as an error
  • transfer the request back to the page itself with Server.Transfer(Context.Request.Url.LocalPath)
  • the page's OnLoad method checks for the error flag and displays a message if present

This ensures the error is handled entirely on the requested page, and the page is capable of reporting errors.

Also note that while the browser will eventually receive a proper response, the browser may take its time uploading the entire request before it handles the server's response and displays it. This behavior is probably defined as part of the server/browser interaction in the HTTP protocol, so probably not much can be done about that.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!