FileUpload e UpdatePanel: ScriptManager.RegisterPostBackControl funciona pela segunda vez

Estou desenvolvendo um aplicativo ASP.NET com C # e Visual Studio 2008 SP1. Estou usando o WebForms.

Eu tenho uma página ASPX com dois UpdatePanels, um à esquerda que contém um TreeView e outro à direita onde eu carrego dinamicamente controles de usuário.

Um controle de usuário, que usei no painel direito, possui um controle FileUpload e um botão para salvar esse arquivo no servidor. O código ascx para salvar o controle é:

        

Eu faço um postback completo para carregar o arquivo para o servidor e salvá-lo no database. Mas eu sempre obtendo False no FileUpload.HasFile.

Eu problema é o UpdatePanel certo. Eu preciso carregar dinamicamente os controles de usuário. Este painel tem três UpdatePanels para carregar os três controles de usuário que eu uso.

Talvez eu possa usar um Uploader de arquivos asynchronouss ou excluir o painel de atualização correto e fazer um postback completo para carregar dinamicamente os controles.

Algum conselho?
ATUALIZAR:

RegisterPostBackControl funciona … a segunda vez que clico no botão salvar. A primeira vez que FileUpload.HasFile é FALSE, e a segunda vez é TRUE.

Segunda atualização
No primeiro clique, também verifico ScriptManager.IsInAsyncPostBack e é FALSE. Eu não entendo nada!

Por quê?

O código para carregar o controle de usuário pela primeira vez e em cada postback é:

 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); } 

Obrigado.

   

    Para mim esta solução funcionou:

    adicione Page.Form.Attributes.Add (“enctype”, “multipart / form-data”);

    O atributo enctype está ausente no primeiro postback.

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

    Coloque o seguinte na sua tag de formulário:

    enctype = “multipart / form-data”

    O preenchimento de upload requer uma postagem completa, e se você usar um painel de atualização, ele faz um post parcial de volta. Então, FileUpload por si só não funcionará. Você terá que lidar com isso de maneira diferente chamando o RegisterPostBackControl .

    Veja este link para mais detalhes -> http://geekswithblogs.net/mmintoff/archive/2009/04/01/fileupload-within-updatepanel.aspx

    Em resposta à sua segunda atualização,

    Eu tive esse problema exato, e acredito que tem a ver com o fato de que você está adicionando um controle dynamic à sua página dentro do UpdatePanel.

    Pode haver uma maneira melhor de fazer isso lá fora, já que eu certamente não sou especialista em ASP.NET, mas consegui resolver esse problema sozinho adicionando o controle em uma div que estava oculta usando CSS – antes – era necessário, e depois auto-incrementar o ID do controle “fictício” para que não haja conflitos, e eu posso continuar adicionando quantos quiser. Dessa forma, quando o UpdatePanel é acionado, ele reconhece totalmente os controles e seus conteúdos, exceto os ocultos, é claro.

    Eu estou usando XSL para transformar meu XML em uma página dinâmica que inclui controles ASP.NET, então essencialmente eu fiz o seguinte:

     

    E então no code-behind:

     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 

    Eu tirei muito do código, mas ele ainda deve ter a idéia geral:

    Eu tive que combinar os dois conselhos aqui. Eu estou usando um UpdatePanel para carregar dinamicamente um UserControl e o FileUpload está no UserControl. Eu precisei:

    • RegisterPostBackControl no Page_Load do controle de usuário

    • adicione enctype = “multipart / form-data” ao elemento form da página, que contém o painel de atualização, o código Page.Form.Attributes.Add (“enctype”, “multipart / form-data”); não funcionou para mim, tinha que ser no aspx

    Espero que isto ajude.

    Funcionou para mim, só quando eu coloquei no 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