FileUpload и UpdatePanel: ScriptManager.RegisterPostBackControl работает во второй раз - PullRequest
8 голосов
/ 15 февраля 2010

Я занимаюсь разработкой приложения ASP.NET с C # и Visual Studio 2008 SP1. Я использую WebForms.

У меня есть страница ASPX с двумя UpdatePanels, одна слева, которая содержит TreeView, а другая справа, где я динамически загружаю пользовательские элементы управления.

Один пользовательский элемент управления, который я использовал на правой панели, имеет элемент управления FileUpload и кнопку для сохранения этого файла на сервере. Код ascx для сохранения управления:

<asp:UpdatePanel ID="UpdatePanelBotons" runat="server" RenderMode="Inline" 
    UpdateMode="Conditional">
<ContentTemplate>
    <asp:Button ID="Save" runat="server" Text="Guardar" 
                onclick="Save_Click" CssClass="button" />
    </ContentTemplate>
    <Triggers>
        <asp:PostBackTrigger ControlID="Save" />
    </Triggers>
</asp:UpdatePanel>

Я делаю полный постбэк, чтобы загрузить файл на сервер и сохранить его в базе данных. Но я всегда получаю False на FileUpload.HasFile.

У меня проблема с правильным UpdatePanel. Мне нужно, чтобы динамически загружать пользовательские элементы управления. Эта панель имеет три панели обновления для загрузки трех пользовательских элементов управления, которые я использую.

Может быть, я могу использовать Async File Uploader или удалить правильную панель обновлений и выполнить полную обратную передачу для динамической загрузки элементов управления.

Любой совет?
UPDATE:

RegisterPostBackControl работает ... второй раз, когда я нажимаю кнопку сохранения. Первый раз FileUpload.HasFile равен FALSE, а второй раз TRUE.

Второе обновление
При первом нажатии я также проверяю ScriptManager.IsInAsyncPostBack и имеет значение FALSE. Я ничего не понимаю !!

Почему?

Код для загрузки пользовательского элемента управления в первый раз и для каждой обратной передачи:

DynamicControls.CreateDestination ud =
            this.LoadControl(ucUrl) as DynamicControls.CreateDestination;
if (ud != null)
{
    Button save = ud.FindControl("Save") as Button;
    if (save != null) 
        ScriptManager1.RegisterPostBackControl(save);
    PanelDestination.Controls.Add(ud);
}

Спасибо.

Ответы [ 6 ]

30 голосов
/ 27 апреля 2010

Для меня это решение сработало:

добавить Page.Form.Attributes.Add ("enctype", "multipart / form-data");

Атрибут enctype отсутствует при первой обратной передаче.

http://adamnoffie.blogspot.com/2007/10/file-upload-not-working-on-first.html

3 голосов
/ 25 октября 2010

Добавьте в тег формы следующее:

ENCTYPE = "многочастному / форм-данных"

1 голос
/ 22 февраля 2011

Я должен был объединить оба совета здесь. Я использую UpdatePanel для динамической загрузки UserControl, а FileUpload находится в UserControl. Я должен был:

  • RegisterPostBackControl в Page_Load пользовательского элемента управления

  • добавить enctype = "multipart / form-data" к элементу формы страницы, который содержит панель обновления, код Page.Form.Attributes.Add ("enctype", "multipart / form-data «); у меня не сработало, должно было быть в aspx

Надеюсь, это поможет.

1 голос
/ 18 марта 2010

В ответ на ваше второе обновление,

У меня была именно эта проблема, и я считаю, что это связано с тем, что вы добавляете динамический элемент управления на свою страницу внутри UpdatePanel.

Возможно, есть лучший способ сделать это, так как я, конечно, не эксперт ASP.NET, но я смог решить эту проблему самостоятельно, добавив элемент управления в div, который был скрыт с помощью CSS -перед - это было необходимо, а затем автоматически увеличивать ID «фиктивного» элемента управления, чтобы не было конфликтов, и я могу продолжать добавлять столько, сколько захочу. Таким образом, при запуске UpdatePanel он полностью распознает элементы управления и их содержимое, за исключением, конечно, скрытых.

Я использую XSL для преобразования своего XML в динамическую страницу с элементами управления ASP.NET, поэтому по сути я сделал следующее:

<div class="hide">
    <asp:FileUpload CssClass="upload" identity="addVersion_{@id}_{count(draft) + 1}" runat="server" />
    <asp:Button Text="Add File" identity="addVersionBtn_{@id}_{count(draft) + 1}" fileControlIdentity="addVersion_{@id}_{count(draft) + 1}" action="addVersion" runat="server" />
</div>

А затем в коде позади:

Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
    //Code to generate the data (stripped out because it is generated in a different manner than the original poster)

    //Add events for all of the new-found controls depending on their type
    recursiveAddEvents(nameOfPlaceHolder.Controls)
End Sub


//Add events for all of the new-found controls depending on their type
Sub recursiveAddEvents(ByRef controls As ControlCollection)
    For Each con As Control In controls
        If con.Controls.Count > 0 Then
            recursiveAddEvents(con.Controls)
        End If

        //Try to cast the control to different data types
        Dim btn As Button = TryCast(con, Button)
        Dim file As FileUpload = TryCast(con, FileUpload)

        //Test to see which type the control was and apply the actions to it
        If Not btn Is Nothing Then
            //Assign the correct click events
            If btn.Attributes.Item("action") = "addVersion" Then
                AddHandler btn.Click, AddressOf addDraftVersion
                btn.ID = btn.Attributes.Item("identity")

                //Register the control with the ScriptManager
                ScriptManager.GetCurrent(Page).RegisterPostBackControl(btn)
            End If
        ElseIf Not file Is Nothing Then
            //Assign the correct click events
            file.ID = file.Attributes.Item("identity")
        End If
    Next
End Sub

Protected Sub addDraftVersion(ByVal sender As Button, ByVal e As EventArgs)
    Dim fileName as String = sender.Attributes("title").Replace(" ", "_") & "_D" & info("draftID") & "_V" & info("versionID")
    Dim inputControl As FileUpload = TryCast(trackPH.FindControl(sender.Attributes("fileControlIdentity")), FileUpload)

    If inputControl Is Nothing Then
        Exit Sub
    End If

    //Do whatever need to be done

    //Trigger UpdatePanel(s)
    nameOfUpdatePanel.Update()
End Sub

Я удалил большую часть кода, но он все же должен дать общее представление:)

1 голос
/ 15 февраля 2010

Заполнить загрузку требуется полный пост, и если вы используете панель обновления, он делает частичный пост обратно. Таким образом, FileUpload сам по себе не будет работать. Вам придется обращаться с этим по-другому, позвонив по номеру RegisterPostBackControl.

Подробности смотрите по этой ссылке -> http://geekswithblogs.net/mmintoff/archive/2009/04/01/fileupload-within-updatepanel.aspx

0 голосов
/ 02 июля 2013

Это сработало для меня, только когда я положил его в Page_Init

Private Sub Page_Init(sender As Object, e As EventArgs) Handles Me.Init
    Page.Form.Attributes.Add("enctype", "multipart/form-data")
End Sub
...