3

Possible Duplicate:
Maximum Request Length Exceeded Not Redirect on Error Page

I try to redirect user to some error page, when he uploads file that exceed maximum size.

I've put in Web.config following line to limit file to 10MB:

<httpRuntime maxRequestLength="10240" executionTimeout="360" />

On my page there's a simply form with standard ASP file upload control and submit button. I've also defined redirection on Page level (I've tried also in Global.asax Application_Error handling, but results are the same):

protected void Page_Error(object sender, EventArgs e)
{
    if (HttpContext.Current.Error is HttpException)
    {
        if ((HttpContext.Current.Error as HttpException).ErrorCode==-2147467259)
        {
            Server.ClearError();
            Response.Redirect("~/Error.aspx");
        }
    }
}

I've tried also Server.Transfer() - not working.

When I try to upload file bigger than 10 MB I can debug and see that the code from Page_Error is being fully executed twice: even with Server.ClearError(), but the page is not redirected to Error.aspx. Instead, the standard, ugly "Connection has been reset" error page appears.

This code works OK if the error is another type, like division by 0 set on Page_Load. Can you tell me what am I doing wrong here?

BTW. I use Visual Web Developer 2010 Express with .NET 4.0, WindowsXP. Testing on buld-in to VWD IIS server.

Community
  • 1
  • 1
mj82
  • 5,193
  • 7
  • 31
  • 39

2 Answers2

1

You may want to try defining the generic error page in your web.config file, rather than handling it through code:

<customErrors defaultRedirect="/Path/to/myErrorPage.aspx" mode="On" />

You can also then define specific pages for each http status code, such as:

<customErrors defaultRedirect="/error/generic.aspx" mode="On">
    <error statusCode="404" redirect="/error/filenotfound.aspx" />
    <error statusCode="500" redirect="/error/server.html" />
</customErrors>

Here's a decent how-to article: http://support.microsoft.com/kb/306355

EDIT: I've posted a suspected duplicate. Check it out in the comments of your question. It looks very similar to yours. Maybe asp.net has a problem handling these types of errors..

EDIT 2: also - I believe the error you're trying to handle is http 413:

<error statusCode="413" redirect="/error/upload.aspx"/>
Community
  • 1
  • 1
KP.
  • 13,218
  • 3
  • 40
  • 60
  • Yes, I forgot to mention that I've tried also that, and it's not changing anything with my problem... – mj82 Oct 05 '12 at 14:43
1

Answer:
OK, so the answer I've found is following: it can't be done via "normal" exception handling. Folowing code, found in one of mentioned link, put in global.asax, is some wokaround:

protected void Application_BeginRequest(Object sender, EventArgs e)
{
    System.Web.Configuration.HttpRuntimeSection runTime = (System.Web.Configuration.HttpRuntimeSection)System.Web.Configuration.WebConfigurationManager.GetSection("system.web/httpRuntime");

    //Approx 100 Kb(for page content) size has been deducted because the maxRequestLength proprty is the page size, not only the file upload size
    int maxRequestLength = (runTime.MaxRequestLength - 100) * 1024;

    //This code is used to check the request length of the page and if the request length is greater than

    //MaxRequestLength then retrun to the same page with extra query string value action=exception

    HttpContext context = ((HttpApplication)sender).Context;
    if (context.Request.ContentLength > maxRequestLength)
    {
        IServiceProvider provider = (IServiceProvider)context;
        HttpWorkerRequest workerRequest = (HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest));

        // Check if body contains data
        if (workerRequest.HasEntityBody())
        {
            // get the total body length
            int requestLength = workerRequest.GetTotalEntityBodyLength();

            // Get the initial bytes loaded
            int initialBytes = 0;

            if (workerRequest.GetPreloadedEntityBody() != null)
                initialBytes = workerRequest.GetPreloadedEntityBody().Length;

            if (!workerRequest.IsEntireEntityBodyIsPreloaded())
            {
                byte[] buffer = new byte[512000];

                // Set the received bytes to initial bytes before start reading
                int receivedBytes = initialBytes;

                while (requestLength - receivedBytes >= initialBytes)
                {
                    // Read another set of bytes
                    initialBytes = workerRequest.ReadEntityBody(buffer, buffer.Length);

                    // Update the received bytes
                    receivedBytes += initialBytes;
                }
                initialBytes = workerRequest.ReadEntityBody(buffer, requestLength - receivedBytes);
            }
        }

        context.Server.ClearError();  //otherwise redirect will not work as expected
        // Redirect the user
        context.Response.Redirect("~/Error.aspx");
    }
}
mj82
  • 5,193
  • 7
  • 31
  • 39