Загрузка файла на сервер автоматически внутри панели обновления не работает в первый раз
Требования
Я пытаюсь загрузить файл, как только пользователь его выберет. Я должен выполнить следующие требования:
- Кнопка выглядит как другие кнопки в приложении.
- Файл загружается, как только пользователь выбирает его.
- Мне нужно, чтобы он находился в UpdatePanel, так как мне нужно сделать условные обновления на странице. я CAN сделать полный ответ на выбранный файл (a.k.a
onchange
).
Текущий код
Вот как выглядит мой файл вида:
<asp:UpdatePanel ID="upData" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<div style="width: auto; float: right;">
<asp:Button ID="btnFileImportSkin" CssClass="ButtonSkin AddButton" Text="Import" Style="position: absolute; z-index: 2;" runat="server" OnClientClick="Javascript:onImport(); return false;" />
<asp:FileUpload ID="fileImport" Visible="false" Style="position:relative; opacity:0;" runat="server" onchange="Javascript:onFileSelected();" />
<%-- onchange="Javascript:this.form.submit();" /> --%>
<%-- <asp:Button ID="btnUpload" runat="server" OnClientClick="Javascript:alert('Uploading...'); __doPostBack('<%= btnUpload.ID %>', ''); return false;" /> --%>
<asp:Button ID="btnUpload" OnClick="btnUpload_Click" runat="server" />
</div>
</ContentTemplate>
<Triggers>
<asp:PostBackTrigger ControlID="btnUpload" />
</Triggers>
</asp:UpdatePanel>
Соответствующий Javascript:
<script type="text/javascript">
function onImport() {
var fileImportClientId = '<%= fileImport.ClientID %>';
document.getElementById(fileImportClientId).click();
}
function onFileSelected() {
alert("File Selected");
// I have tried calling the function directly and with a timeout
setTimeout(onUpload, 20);
}
function onUpload() {
var btnUploadClientId = '<%= btnUpload.ClientID %>';
document.getElementById(btnUploadClientId).click();
}
</script>
Код позади:
protected void btnUpload_Click(object sender, EventArgs e)
{
// PostedFile is null first time code gets here on user selecting a file
if (fileImport.PostedFile != null)
{
if (fileImport.PostedFile.FileName.Length > 0)
{
ImportFromFile();
}
}
}
Объяснение/Поток
- Пользователь нажимает кнопку
btnFileImportSkin
.
- Вызывается функция
onImport
, которая программным образом нажимает кнопку fileimport
.
- Пользователь выбирает файл и нажимает кнопку "Открыть".
-
onFileSelected
.
-
onUpload
называется успешно.
-
btnUpload_Click
вызывается успешно каждый раз.
Однако проблема заключается в том, что
fileImport.PostedFile имеет значение null при первом выборе пользователем файла. Все работает отлично во второй раз и оттуда.
Похожие
Этот вопрос тесно связан с моей проблемой, но OP, вероятно, захотел загрузить Async, как в Gmail. Я уже пробовал сделать следующее, как в ответах на этот вопрос:
- __ doPostBack() в событии OnClientClick
btnUpload
- this.form.submit() onchange события моего элемента управления
FileUpload
.
- Настройка атрибута onchange элемента управления
FileUpload
в Page_PreRender
Дополнительные примечания
- Эта вещь отлично работала, когда у меня не было панелей обновления. Я делал this.form.submit() непосредственно в событии onchange элемента управления
FileUpload
.
- Целевая структура .NET 4.0
ПРИМЕЧАНИЕ. В приведенном выше элементе управления FileUpload
добавлен Visible = "false". Это была проблема, но я игнорировал ее, задавая вопрос.
Ответы
Ответ 1
С подсказкой от ответа BeeTee, еще SO post и этот поток на другом форуме, я узнал, что элемент управления FileUpload должен быть виден во время предварительного запуска. Вероятно, это верно для любых родительских UpdatePanels, в которых находится этот элемент управления. Таким образом, в основном я удалил Visible=false
из моего определения управления ниже:
<asp:FileUpload ID="fileImport" Visible="false" Style="position:relative; opacity:0;" runat="server" onchange="Javascript:onFileSelected();" />
В моем случае я мог бы скрыть его, установив свойство css opacity
равным 0. Однако есть еще два пути:
- Задайте свойство css
display:none
- Сделать управление asp визуализируемым свойством временно на true во время prerendering. Это подробно описано в приведенной выше теме с другого форума.
Обратите внимание, что Visible также должен быть прав для родителей этого элемента управления FileUpload, как указано в другом потоке SO.
Ответ 2
Этот код работает для меня, когда вы нацеливаетесь на версии .Net 4.5 и 4.0. Я копирую/вставляю ваш код в новое приложение Web Forms, и в обоих случаях fileImport.PostedFile не был нулевым, но содержал поток выбранного изображения.
Есть ли проблема в любой другой разметке на вашей странице? Или, возможно, жизненный цикл вашей страницы? Является ли html/javascript вы отправили на пользовательский элемент управления или страницу веб-формы?