Подтвердить что ты не робот

Файл слишком большой при загрузке файла с помощью asp: FileUpLoad control

Я использую asp:FileUpLoad для загрузки файлов в мой проект asp.net c#. Все это работает отлично, если размер файла не превышает максимально допустимого. При превышении максимального значения. Я получаю сообщение об ошибке "Internet Explorer cannot display the webpage". Проблема заключается в том, что блок catch try не обнаруживает ошибку, поэтому я не могу дать user a friendly message, что они превысили допустимый размер. Я видел эту проблему во время поиска в Интернете, но я не могу найти приемлемого решения.

Я бы посмотрел на другие элементы управления, но мое управление, вероятно, не пошло бы на покупку стороннего элемента управления.

В свете ответа, предлагающего ajac, мне нужно добавить этот комментарий. Я пытался загрузить элементы управления ajax несколько месяцев назад. Как только я использую элемент управления ajax, я получаю эту ошибку компиляции.

Ошибка 98 Тип "System.Web.UI.ScriptControl" определен в сборку, на которую не ссылаются. Вы должны добавить ссылку на сборку 'System.Web.Extensions, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = 31bf3856ad364e35'.

Я мог бы избавиться от него, хотя я добавил "System.Web.Extensions". Поэтому я отказался от Ajax и использовал другие методы.

Поэтому мне нужно решить эту проблему или полностью новое решение.

4b9b3361

Ответ 1

Предел размера файла по умолчанию - (4 МБ), но вы можете изменить ограничение по умолчанию локализованным способом, отбросив файл web.config в каталоге, в котором живет ваша страница загрузки. Таким образом, вам не нужно делать весь сайт допустимым для огромных загрузок (это может открыть вам определенные виды атак).

Просто установите его в web.config в разделе <system.web>. например В приведенном ниже примере я устанавливаю максимальную длину, чтобы 2GB

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

Обратите внимание, что maxRequestLength установлен в КБ, и его можно настроить на 2GB (2079152 KB's). Практически нам не нужно часто задавать длину запроса 2GB, но если вы установите длину запроса выше, нам также необходимо увеличить значение 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.)

Подробнее читайте httpRuntime Element (Схема настроек ASP.NET)

Теперь, если вы хотите показать пользовательское сообщение пользователю, если размер файла больше 100MB.

Вы можете сделать это как..

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.";
}

Ответ 2

  • На клиенте API Flash и/или ActiveX и/или Java и/или HTML5 файлы являются единственными способами проверки размера файла и предотвращения отправки. Используя обертку/плагин, например Uploadify, вам не нужно сворачивать самостоятельно, и вы получаете кросс-браузерное решение.

  • На сервере в global.asax поставьте это:

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

    Создайте класс BasePage, который ваши страницы наследуют и добавят к нему этот код:

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

    Наконец, в web.config вы ДОЛЖНЫ установить maxAllowedContentLength (в байтах) больше, чем maxRequestLength (в kB).

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

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

Ответ 3

Действительно, попытка catch не поможет вам. Но вот обходной путь: вы можете обработать ошибку в вашем методе Global.asax Application_Error.

Пример:

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");

}

Конечно, имейте в виду, что если какая-либо другая ошибка возникает на вашей странице "mypage", вы будете перенаправлены на /my -upload-error-message.aspx, независимо от того, что произошло.

Ответ 5

Кажется, это проблема тайм-аута сеанса, увеличения времени сеанса, а затем повторите попытку. Вы можете установить тайм-аут сеанса в файле web.config

Ответ 6

В вашем web.config установите максимально допустимую длину контента выше, чем вы хотите принять:

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

Затем в global.asax используйте Application_BeginRequest, чтобы установить свой лимит:

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