Ajax AsyncFileUpload.FileBytes возвращает ноль

У меня есть страница загрузки файлов с элементом управления AsyncFileUpload. Когда пользователь просматривает файл, элемент управления загрузкой загружает файл в память. Затем у меня есть кнопка «Загрузить», которая запускает следующий код для сохранения файла в базе данных.

Я обнаружил, что если размер файлов превышает 500 КБ, то свойство FileBytes элемента управления просто возвращает значение null. Это происходит на моем сервере, но при локальном запуске приложение работает нормально.

Я не обрабатываю событие OnUploadCompleted, так как мне нужно, чтобы пользователь заполнил дополнительную информацию перед фиксацией файла в базе данных.

У меня есть это в моем web.config: httpRuntime maxRequestLength="10000"/>

private void UploadDocument(int mietID)
{
    if (Page.IsValid)
    {
        if (mietID > 0)
        {
            if (File1.HasFile && File1.FileBytes != null)
            {
                string[] docFormats = MIETPConfig.Current.SupportedDocumentFormats;

                for (short i = 0; i < docFormats.Length; i++)
                    docFormats[i] = docFormats[i].ToUpper();

                if (docFormats.Contains(Path.GetExtension(File1.FileName).ToUpper()))
                {
                    try
                    {
                        byte[] uploadedBytes = File1.FileBytes;
                        DocumentController.CreateDocument(txtLinkText.Text, Path.GetFileName(File1.PostedFile.FileName), uploadedBytes, mietID, (User)Session["User"]);

                        MietpClientScripts.CloseWindow(Page);
                    }
                    catch (Exception)
                    {
                        lblUploadStatus.Text = "There was an error saving the document to the database.";
                    }
                }
                else
                {
                    System.Text.StringBuilder sb = new System.Text.StringBuilder();
                    foreach (string s in docFormats)
                        sb.Append(s + ", ");

                    sb.Remove(sb.Length - 2, 2);
                    lblUploadStatus.Text = "Invalid file format, only these formats are supported: " + sb.ToString();
                }
            }
            else
            {
                lblUploadStatus.Text = "There was an error saving the document, the document could not be read; it might be too large to upload.";
            }
        }
        else
            lblUploadStatus.Text = "No Mietp ID to associate document with.";
    }
}

person David Neale    schedule 25.01.2010    source источник


Ответы (3)


Я не совсем уверен, но могу предположить, что максимальное количество байтов в FileBytes ограничено из-за того, что загрузка большого количества файлов займет много оперативной памяти. Ваш хостинг-партнер мог ограничить это. Вероятно, ваш хостер по умолчанию установил <httpRuntime maxRequestLength="XXX" /> на 512 КБ.

Попробуйте сохранить файл с помощью SaveAs(path). Это в основном то, что вы делаете на этом этапе, но вы позволите элементу управления выяснить, когда сбрасывать в файл, избегая захвата всего файла в памяти, или захватывать файловый поток с помощью FileContent, если вам действительно нужен доступ к необработанному содержимому. . Также измените <httpRuntime maxRequestLength="XXX" /> на что-то вроде 102400, чтобы переопределить настройки по умолчанию от вашего хостера.

person Jan Jongboom    schedule 25.01.2010
comment
Извините, я пропустил это за пределами поста - у меня maxRequestLength был установлен на 10000, но сейчас я попробовал его с 102400. Я пытался использовать поток из FileContent, но метод чтения ничего не возвращает, хотя свойство Length дает правильное количество байтов. File.SaveAs выдает ObjectDisposedException (не может получить доступ к закрытому файлу) всякий раз, когда FileBytes имеют значение null. - person David Neale; 26.01.2010
comment
Если просто поставить: void UploadDocument() { File1.SaveAs(Server.MapPath("~/myuploadedfile.tmp")); } вместо всей логики теперь; это правильно сохраняет файл? Если нет, работает ли это, когда вы используете обычный FileUpload вместо AJAX? - person Jan Jongboom; 26.01.2010
comment
Нет, файл не сохранится, даже если я уберу логику. Я сделал прямую замену на элемент управления FileUpload, и он отлично работает с каждым документом, даже с 15 МБ. - person David Neale; 26.01.2010
comment
Я предполагаю, что вы запускаете событие слишком рано: на вашем локальном компьютере в тот момент, когда вы запускаете событие, контент уже загружен, так как локальная загрузка происходит молниеносно. Remote событие запускается, пока компонент еще не завершен. К какому событию привязано UploadDocument? Это должно быть не кнопка или что-то в этом роде, а событие из компонента FileUpload, и я не понимаю, почему вы не можете использовать OnUploadCompleted? - person Jan Jongboom; 26.01.2010
comment
Я не думаю, что это все. Событие на стороне сервера OnUploadCompleted вызывается перед вызовом сценариев на стороне клиента. Я нажимаю кнопку и после этого вызываю свой метод UploadDocument. - person David Neale; 26.01.2010

Я думаю, что нашел решение этой проблемы: в событии OnUploadComplete просто поместите в сеанс FileBytes и получите его в своем событии Button_Click. По какой-то причине байты вашего загруженного файла стираются из сеанса после второй обратной передачи...

Это работает для меня. Ура Лоран

person Laurent    schedule 08.02.2010
comment
Хорошее предложение - звучит так, как будто оно выполнило бы то, что я пытался сделать. Хотя я только что написал сценарий для простого старого элемента управления FileUpload. Я предполагаю, что опасность заключается в том, что кнопка может быть нажата слишком рано, особенно с большим файлом, и значение все равно будет нулевым; это также вызовет обратную передачу, поэтому никогда не будет завершено. - person David Neale; 09.02.2010

Когда вы используете AsyncFileUpload, вы должны установить правильные параметры в теге form, который размещен на вашей странице или мастер-странице:

 <form id="form1" runat="server" enctype="multipart/form-data" method="post">

Если вы не установите правильный тип enctype и метод, UploadedComplete никогда не сработает, и вы не сможете получить FileUpload.FileBytes, поскольку FileUpload.HasFile< /strong> возвращает true только во время выполнения UploadedComplete.

Я предполагаю, что на вашей странице вы не установили правильный enctype.

Кроме того, предыдущие версии AsyncFileUpload не работали в Chrome. Июльская версия 2011 г. (4.1.50731.0) решила проблему.

person Emanuele Greco    schedule 06.10.2011