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

Загрузка файла на сервер автоматически внутри панели обновления не работает в первый раз

Требования

Я пытаюсь загрузить файл, как только пользователь его выберет. Я должен выполнить следующие требования:

  • Кнопка выглядит как другие кнопки в приложении.
  • Файл загружается, как только пользователь выбирает его.
  • Мне нужно, чтобы он находился в 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". Это была проблема, но я игнорировал ее, задавая вопрос.

4b9b3361

Ответ 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 вы отправили на пользовательский элемент управления или страницу веб-формы?