开发者

File too big when uploading a file with the asp:FileUpLoad control

I am using the asp:FileUpLoad to upload files in my asp.net c# project. This all works fine as long as the file size does not exceed the maximum allowed. When the maximum is exceeded. I get an error "Internet Explorer cannot display the webpage". The problem is the try catch block doesn't catch the error so I cannot give the user a friendly message that they have excced the allowable size. I have seen this problem while searching the web but I cannot find an a开发者_StackOverflowcceptable solution.

I would look at other controls, but my managemment probably wouldn't go for buying a third-party control.

In light of answer suggesting ajac, I need to add this comment. I tried to load the ajax controls months ago. As soon as I use an ajax control, I get this compile error.

Error 98 The type 'System.Web.UI.ScriptControl' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.

I could get rid of it although I did add 'System.Web.Extensions'. So I abandoned Ajax and used other techniques.

So I need to solved this problem or a completely new solution.


The default file size limit is (4MB) but you can change the default limit in a localized way by dropping a web.config file in the directory where your upload page lives. That way you don't have to make your whole site allow huge uploads (doing so would open you up to a certain kinds of attacks).

Just set it in web.config under the <system.web> section. e.g. In the below example I am setting the maximum length that to 2GB

<httpRuntime maxRequestLength="2097152" executionTimeout="600" />

Please note that the maxRequestLength is set in KB's and it can be set up to 2GB (2079152 KB's). Practically we don't often need to set the 2GB request length, but if you set the request length higher, we also need to increase the executionTimeout.

Execution Timeout Specifies the maximum number of seconds that a request is allowed to execute before being automatically shut down by ASP.NET. (Default time is 110 seconds.)

For Details please read httpRuntime Element (ASP.NET Settings Schema)

Now if you want to show the custom message to user, if the file size is greater than 100MB.

You can do it like..

if (FileUpload1.HasFile && FileUpload1.PostedFile.ContentLength > 104857600)
{
    //FileUpload1.PostedFile.ContentLength -- Return the size in bytes
    lblMsg.Text = "You can only upload file up to 100 MB.";
}


  1. At the client, Flash and/or ActiveX and/or Java and/or HTML5 Files API are the only ways to test file size and prevent submit. Using a wrapper/plug-in like Uploadify, you don't have to roll your own and you get a cross-browser solution.

  2. On the server, in global.asax, put this:

    public const string MAXFILESIZEERR = "maxFileSizeErr";
    
    public int MaxRequestLengthInMB
    {
        get
        {
            string key = "MaxRequestLengthInMB";
    
            double maxRequestLengthInKB = 4096; /// This is IIS' default setting 
    
            if (Application.AllKeys.Any(k => k == key) == false)
            {
                var section = ConfigurationManager.GetSection("system.web/httpRuntime") as HttpRuntimeSection;
                if (section != null)
                    maxRequestLengthInKB = section.MaxRequestLength;
    
                Application.Lock();
                Application.Add(key, maxRequestLengthInKB);
                Application.UnLock();
            }
            else
                maxRequestLengthInKB = (double)Application[key];
    
            return Convert.ToInt32(Math.Round(maxRequestLengthInKB / 1024));
        }
    }
    
    void Application_BeginRequest(object sender, EventArgs e)
    {
        HandleMaxRequestExceeded(((HttpApplication)sender).Context);
    }
    
    void HandleMaxRequestExceeded(HttpContext context)
    {
        /// Skip non ASPX requests.
        if (context.Request.Path.ToLowerInvariant().IndexOf(".aspx") < 0 && !context.Request.Path.EndsWith("/"))
            return;
    
        /// Convert folder requests to default doc; 
        /// otherwise, IIS7 chokes on the Server.Transfer.
        if (context.Request.Path.EndsWith("/"))
            context.RewritePath(Request.Path + "default.aspx");
    
        /// Deduct 100 Kb for page content; MaxRequestLengthInMB includes 
        /// page POST bytes, not just the file upload.
        int maxRequestLength = MaxRequestLengthInMB * 1024 * 1024 - (100 * 1024);
    
        if (context.Request.ContentLength > maxRequestLength)
        {
            /// Need to read all bytes from request, otherwise browser will think
            /// tcp error occurred and display "uh oh" screen.
            ReadRequestBody(context);
    
            /// Set flag so page can tailor response.
            context.Items.Add(MAXFILESIZEERR, true);
    
            /// Transfer to original page.
            /// If we don't Transfer (do nothing or Response.Redirect), request
            /// will still throw "Maximum request limit exceeded" exception.
            Server.Transfer(Request.Path);
        }
    }
    
    void ReadRequestBody(HttpContext context)
    {
        var provider = (IServiceProvider)context;
        var 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);
            }
        }
    }
    

    Create a BasePage class that your pages will inherit and add this code to it:

    public int MaxRequestLengthInMB
    {
        get
        {
            return (Context.ApplicationInstance as Global).MaxRequestLengthInMB;
        }
    }
    
    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
    
        CheckMaxFileSizeErr();
    }
    
    private void CheckMaxFileSizeErr()
    {
        string key = Global.MAXFILESIZEERR;
        bool isMaxFileSizeErr = (bool)(Context.Items[key] ?? false);
        if (isMaxFileSizeErr)
        {
            string script = String.Format("alert('Max file size exceeded. Uploads are limited to approximately {0} MB.');", MaxRequestLengthInMB);
            ScriptManager.RegisterClientScriptBlock(this, this.GetType(), key, script, true);
        }
    }
    

    Finally, in web.config, you MUST set maxAllowedContentLength (in bytes) greater than maxRequestLength (in kB).

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

<system.webServer>
  <security>
    <requestFiltering>
      <requestLimits maxAllowedContentLength="2000000000" />
    </requestFiltering>
  </security>
</system.webServer>


Indeed, a try catch won't help you. But here is a workaround : you could handle the error in your Global.asax Application_Error method.

Example :

void Application_Error(object sender, EventArgs e) 
{
    // manage the possible 'Maximum Length Exceeded' exception
    HttpContext context = ((HttpApplication)sender).Context;
    /* test the url so that only the upload page leads to my-upload-error-message.aspx in case of problem */
    if (context.Request.Url.PathAndQuery.Contains("mypage"))
        Response.Redirect("/my-upload-error-message.aspx");

}

Of course , be aware that if any other kind of error occurs on your "mypage" page, you will be redirected to the /my-upload-error-message.aspx, regardless of what happened.


You can try the asp.net tool kit upload control. It's free!

http://www.asp.net/ajax/ajaxcontroltoolkit/samples/AsyncFileUpload/AsyncFileUpload.aspx


This seems to be problem of session timeout, increase session time and then try again. You can set session timout in web.config file


In your web.config, set the max allowed content lenght higher than what you want to accept:

<system.webServer>
  <security>
    <requestFiltering>
      <requestLimits maxAllowedContentLength="2000000000" />
    </requestFiltering>
  </security>
</system.webServer>

Then, in global.asax, use Application_BeginRequest to set your own limit:

  private const int MyMaxContentLength = 10000; //Wathever you want to accept as max file.
  protected void Application_BeginRequest(object sender, EventArgs e)
  {
     if (  Request.HttpMethod == "POST"
        && Request.ContentLength > MyMaxContentLength)
     {
        Response.Redirect ("~/errorFileTooBig.aspx");
     }
  }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜