FileUpload and UpdatePanel: ScriptManager.RegisterPostBackControl works the second time
I'm developing an ASP.NET application with C# and Visual Studio 2008 SP1. I'm using WebForms.
I have an ASPX page with two UpdatePanels, one on the left that holds a TreeView and other on the right where I load dynamically user controls.
One user control, that I used on right panel, has a FileUpload control and a button to save that file on server. The ascx code to save control is:
<asp:UpdatePanel ID="UpdatePanelBotons" runat="server" RenderMode="Inline"
UpdateMode="Conditional">
<ContentTemplate>
<asp:Button ID="Save" runat="server" Text="Guardar"
onclick="Save_Cl开发者_开发技巧ick" CssClass="button" />
</ContentTemplate>
<Triggers>
<asp:PostBackTrigger ControlID="Save" />
</Triggers>
</asp:UpdatePanel>
I make a full postback to upload the file to the server and save it to database. But I always getting False on FileUpload.HasFile.
I problem is the right UpdatePanel. I need it to load dynamically the user controls. This panel has three UpdatePanels to load the three user controls that I use.
Maybe I can use an Async File Uploader or delete the right Update Panel and do a full postback to load controls dynamically.
Any advice?
UPDATE:
RegisterPostBackControl
works... the second time I click on save button. First time FileUpload.HasFile is FALSE, and second time is TRUE.
Second Update
On first click I also check ScriptManager.IsInAsyncPostBack and is FALSE. I don't understand ANYTHING!!Why?
The code to load user control first time, and on each postback is:
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);
}
Thank you.
For me this solution worked:
add Page.Form.Attributes.Add("enctype", "multipart/form-data");
The enctype attribute is missing on the first postback.
http://adamnoffie.blogspot.com/2007/10/file-upload-not-working-on-first.html
Put the following in your form tag:
enctype="multipart/form-data"
Fill Upload requires a full post, and if you use a Update Panel, it does a partial post back. So, FileUpload by itself will not work. You will have to handle it differently by calling the RegisterPostBackControl
.
See this link for details --> http://geekswithblogs.net/mmintoff/archive/2009/04/01/fileupload-within-updatepanel.aspx
In response to your second update,
I had this exact problem, and I believe it has to do with the fact that you are adding a dynamic control to your page inside of the UpdatePanel.
There may be a better way to do it out there, as I am certainly no ASP.NET expert, but I was able to solve this problem on my own by adding the control in a div that was hidden using CSS -before- it was needed, and then auto-incrementing the "dummy" control's ID so there are no conflicts, and I can keep adding as many as I want. That way, when the UpdatePanel is triggered it fully recognizes the controls and their contents, excepting the hidden ones of course.
I am using XSL to transform my XML into a dynamic page that includes ASP.NET controls, so essentially I did the following:
<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>
And then in the 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
I stripped out a lot of the code, but it should still get the general idea across :)
I had to combine both advices here. I am using an UpdatePanel to dynamically load an UserControl and the FileUpload is in the UserControl. I had to:
RegisterPostBackControl in the user control's Page_Load
add enctype="multipart/form-data" to the form element of the page, which contains the update panel, the code Page.Form.Attributes.Add("enctype", "multipart/form-data"); didn't work for me, it had to be in the aspx
Hope this helps.
It worked for me, only when I put it in the 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
精彩评论