Файл слишком большой при загрузке файла с помощью элемента управления asp: FileUpLoad - PullRequest
23 голосов
/ 13 июля 2011

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

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

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

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

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

Так что мне нужно решить эту проблему или совершенно новое решение.

Ответы [ 6 ]

30 голосов
/ 13 июля 2011

Ограничение размера файла по умолчанию (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 (схема настроек 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.";
}
3 голосов
/ 31 июля 2011
  1. На клиенте Flash и / или ActiveX, и / или Java, и / или HTML5 Files API являются единственными способами проверить размер файла и предотвратить отправку.Используя оболочку / плагин, такой как Uploadify , вам не нужно накатывать свои собственные, и вы получаете кросс-браузерное решение.

  2. На сервере,в 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 (в кБ).

</p> <pre><system.web> <httpRuntime maxRequestLength="32400" /> </system.web> <system.webServer> <security> <requestFiltering> <requestLimits maxAllowedContentLength="2000000000" /> </requestFiltering> </security> </system.webServer>

2 голосов
/ 27 июля 2011

Действительно, попытка поймать вас не поможет. Но есть обходной путь: вы можете обработать ошибку в вашем методе 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, независимо от того, что произошло.

1 голос
/ 13 июля 2011

Вы можете попробовать элемент управления загрузкой набора инструментов asp.net. Это бесплатно!

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

0 голосов
/ 04 августа 2011

В вашем файле 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");
     }
  }
0 голосов
/ 13 июля 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...