Marcus L
Marcus L

Reputation: 4078

Catching "Maximum request length exceeded"

I'm writing an upload function, and have problems catching "System.Web.HttpException: Maximum request length exceeded" with files larger than the specified max size in httpRuntimein web.config (max size set to 5120). I'm using a simple <input> for the file.

The problem is that the exception is thrown before the upload button's click-event, and the exception happens before my code is run. So how do I catch and handle the exception?

EDIT: The exception is thrown instantly, so I'm pretty sure it's not a timeout issue due to slow connections.

Upvotes: 114

Views: 154041

Answers (16)

Jonathan Parker
Jonathan Parker

Reputation: 6795

As GateKiller said you need to change the maxRequestLength. You may also need to change the executionTimeout in case the upload speed is too slow. Note that you don't want either of these settings to be too big otherwise you'll be open to DOS attacks.

The default for the executionTimeout is 360 seconds or 6 minutes.

You can change the maxRequestLength and executionTimeout with the httpRuntime Element.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.web>
        <httpRuntime maxRequestLength="102400" executionTimeout="1200" />
    </system.web>
</configuration>

EDIT:

If you want to handle the exception regardless then as has been stated already you'll need to handle it in Global.asax. Here's a link to a code example.

Upvotes: 58

pmcs
pmcs

Reputation: 71

Following up on Martin van Bergeijk's answer, I added an additional if block to check if they actually selected a file before submission.

if(input.files[0] == null)
{lbl.innertext = "You must select a file before selecting Submit"}
return false;        

Upvotes: 0

Martin van Bergeijk
Martin van Bergeijk

Reputation: 21

I'm using a FileUpload control and client side script to check the file size.
HTML (note the OnClientClick - executed before OnClick):

<asp:FileUpload ID="FileUploader" runat="server" />
<br />
<asp:Button ID="btnUpload" Text="Upload" runat="server" OnClientClick="return checkFileSize()" OnClick="UploadFile" />
<br />
<asp:Label ID="lblMessage" runat="server" CssClass="lblMessage"></asp:Label>

Then the script (note the 'return false' if the size is too big: this is to cancel the OnClick):

function checkFileSize() 
{
    var input = document.getElementById("FileUploader");
    var lbl = document.getElementById("lblMessage");
    if (input.files[0].size < 4194304)
    {
        lbl.className = "lblMessage";
        lbl.innerText = "File was uploaded";
    }
    else
    {
        lbl.className = "lblError";
        lbl.innerText = "Your file cannot be uploaded because it is too big (4 MB max.)";
        return false;
    }
}

Upvotes: 2

Raghav
Raghav

Reputation: 9628

It can be checked via:

        var httpException = ex as HttpException;
        if (httpException != null)
        {
            if (httpException.WebEventCode == System.Web.Management.WebEventCodes.RuntimeErrorPostTooLarge)
            {
                // Request too large

                return;

            }
        }

Upvotes: 0

jazzcat
jazzcat

Reputation: 4451

As you probably know, the maximum request length is configured in TWO places.

  1. maxRequestLength - controlled at the ASP.NET app level
  2. maxAllowedContentLength - under <system.webServer>, controlled at the IIS level

The first case is covered by other answers to this question.

To catch THE SECOND ONE you need to do this in global.asax:

protected void Application_EndRequest(object sender, EventArgs e)
{
    //check for the "file is too big" exception if thrown at the IIS level
    if (Response.StatusCode == 404 && Response.SubStatusCode == 13)
    {
        Response.Write("Too big a file"); //just an example
        Response.End();
    }
}

Upvotes: 2

Khoa Tran
Khoa Tran

Reputation: 131

How about catch it at EndRequest event?

protected 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);
        }
    }

Upvotes: 0

Diego
Diego

Reputation: 2372

After tag

<security>
     <requestFiltering>
         <requestLimits maxAllowedContentLength="4500000" />
     </requestFiltering>
</security>

add the following tag

 <httpErrors errorMode="Custom" existingResponse="Replace">
  <remove statusCode="404" subStatusCode="13" />
  <error statusCode="404" subStatusCode="13" prefixLanguageFilePath="" path="http://localhost/ErrorPage.aspx" responseMode="Redirect" />
</httpErrors>

you can add the Url to the error page...

Upvotes: 1

Damien McGivern
Damien McGivern

Reputation: 4004

There is no easy way to catch such exception unfortunately. What I do is either override the OnError method at the page level or the Application_Error in global.asax, then check if it was a Max Request failure and, if so, transfer to an error page.

protected override void OnError(EventArgs e) .....


private void Application_Error(object sender, EventArgs e)
{
    if (GlobalHelper.IsMaxRequestExceededException(this.Server.GetLastError()))
    {
        this.Server.ClearError();
        this.Server.Transfer("~/error/UploadTooLarge.aspx");
    }
}

It's a hack but the code below works for me

const int TimedOutExceptionCode = -2147467259;
public static bool IsMaxRequestExceededException(Exception e)
{
    // unhandled errors = caught at global.ascx level
    // http exception = caught at page level

    Exception main;
    var unhandled = e as HttpUnhandledException;

    if (unhandled != null && unhandled.ErrorCode == TimedOutExceptionCode)
    {
        main = unhandled.InnerException;
    }
    else
    {
        main = e;
    }


    var http = main as HttpException;

    if (http != null && http.ErrorCode == TimedOutExceptionCode)
    {
        // hack: no real method of identifying if the error is max request exceeded as 
        // it is treated as a timeout exception
        if (http.StackTrace.Contains("GetEntireRawContent"))
        {
            // MAX REQUEST HAS BEEN EXCEEDED
            return true;
        }
    }

    return false;
}

Upvotes: 97

Serge Shultz
Serge Shultz

Reputation: 6068

Here's an alternative way, that does not involve any "hacks", but requires ASP.NET 4.0 or later:

//Global.asax
private void Application_Error(object sender, EventArgs e)
{
    var ex = Server.GetLastError();
    var httpException = ex as HttpException ?? ex.InnerException as HttpException;
    if(httpException == null) return;

    if(httpException.WebEventCode == WebEventCodes.RuntimeErrorPostTooLarge)
    {
        //handle the error
        Response.Write("Sorry, file is too big"); //show this message for instance
    }
}

Upvotes: 8

Nasurudeen
Nasurudeen

Reputation: 3

You can solve this by increasing the maximum request length and execution time out in your web.config:

-Please Clarify the maximum execution time out grater then 1200

<?xml version="1.0" encoding="utf-8"?> <configuration> <system.web> <httpRuntime maxRequestLength="102400" executionTimeout="1200" /> </system.web> </configuration>

Upvotes: 0

user3767204
user3767204

Reputation:

In IIS 7 and beyond:

web.config file:

<system.webServer>
  <security >
    <requestFiltering>
      <requestLimits maxAllowedContentLength="[Size In Bytes]" />
    </requestFiltering>
  </security>
</system.webServer>

You can then check in code behind, like so:

If FileUpload1.PostedFile.ContentLength > 2097152 Then ' (2097152 = 2 Mb)
  ' Exceeded the 2 Mb limit
  ' Do something
End If

Just make sure the [Size In Bytes] in the web.config is greater than the size of the file you wish to upload then you won't get the 404 error. You can then check the file size in code behind using the ContentLength which would be much better

Upvotes: 3

BaggieBoy
BaggieBoy

Reputation: 57

One way to do this is to set the maximum size in web.config as has already been stated above e.g.

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

then when you handle the upload event, check the size and if its over a specific amount, you can trap it e.g.

protected void btnUploadImage_OnClick(object sender, EventArgs e)
{
    if (fil.FileBytes.Length > 51200)
    {
         TextBoxMsg.Text = "file size must be less than 50KB";
    }
}

Upvotes: 4

Andrew
Andrew

Reputation: 1746

If you are wanting a client side validation also so you get less of a need to throw exceptions you could try to implement client side file size validation.

Note: This only works in browsers that support HTML5. http://www.html5rocks.com/en/tutorials/file/dndfiles/

<form id="FormID" action="post" name="FormID">
    <input id="target" name="target" class="target" type="file" />
</form>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" type="text/javascript"></script>

<script type="text/javascript" language="javascript">

    $('.target').change(function () {

        if (typeof FileReader !== "undefined") {
            var size = document.getElementById('target').files[0].size;
            // check file size

            if (size > 100000) {

                $(this).val("");

            }
        }

    });

</script>

Upvotes: 10

Marcus
Marcus

Reputation: 2480

A solution that works with IIS7 and upwards: Display custom error page when file upload exceeds allowed size in ASP.NET MVC

Upvotes: 3

Vinod T. Patil
Vinod T. Patil

Reputation: 2959

Hi solution mentioned by Damien McGivern, Works on IIS6 only,

It does not work on IIS7 and ASP.NET Development Server. I get page displaying "404 - File or directory not found."

Any ideas?

EDIT:

Got it... This solution still doesn't work on ASP.NET Development Server, but I got the reason why it was not working on IIS7 in my case.

The reason is IIS7 has a built-in request scanning which imposes an upload file cap which defaults to 30000000 bytes (which is slightly less that 30MB).

And I was trying to upload file of size 100 MB to test the solution mentioned by Damien McGivern (with maxRequestLength="10240" i.e. 10MB in web.config). Now, If I upload the file of size > 10MB and < 30 MB then the page is redirected to the specified error page. But if the file size is > 30MB then it show the ugly built-in error page displaying "404 - File or directory not found."

So, to avoid this, you have to increase the max. allowed request content length for your website in IIS7. That can be done using following command,

appcmd set config "SiteName" -section:requestFiltering -requestLimits.maxAllowedContentLength:209715200 -commitpath:apphost

I have set the max. content length to 200MB.

After doing this setting, the page is succssfully redirected to my error page when I try to upload file of 100MB

Refer, http://weblogs.asp.net/jgalloway/archive/2008/01/08/large-file-uploads-in-asp-net.aspx for more details.

Upvotes: 9

GateKiller
GateKiller

Reputation: 75969

You can solve this by increasing the maximum request length in your web.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.web>
        <httpRuntime maxRequestLength="102400" />
    </system.web>
</configuration>

The example above is for a 100Mb limit.

Upvotes: 20

Related Questions