2010-02-15 4 views
7

Je développe une application ASP.NET avec C# et Visual Studio 2008 SP1. J'utilise WebForms.FileUpload et UpdatePanel: ScriptManager.RegisterPostBackControl fonctionne la deuxième fois

J'ai une page ASPX avec deux UpdatePanels, un sur la gauche qui contient un TreeView et l'autre sur la droite où je charge dynamiquement les contrôles utilisateur.

Un contrôle d'utilisateur, que j'ai utilisé sur le panneau droit, a un contrôle FileUpload et un bouton pour enregistrer ce fichier sur le serveur. Le code ascx pour sauver le contrôle est:

<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> 

Je fais une publication complète pour télécharger le fichier sur le serveur et l'enregistrer dans la base de données. Mais je reçois toujours False sur FileUpload.HasFile.

Le problème est le bon UpdatePanel. J'en ai besoin pour charger dynamiquement les contrôles utilisateur. Ce panneau a trois UpdatePanels pour charger les trois contrôles utilisateur que j'utilise. Peut-être que je peux utiliser un téléchargeur de fichiers Async ou supprimer le bon panneau de mise à jour et faire une publication complète pour charger les contrôles de façon dynamique.

Un conseil?
MISE À JOUR:

RegisterPostBackControlfonctionne ... la deuxième fois que je clique sur le bouton Enregistrer. La première fois FileUpload.HasFile est FALSE, et la deuxième fois est TRUE.

Deuxième mise à jour
Le premier clic je vérifie également ScriptManager.IsInAsyncPostBack et est FAUX. Je ne comprends rien

Pourquoi?

Le code pour charger première fois le contrôle de l'utilisateur, et sur chaque postback est:

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

Merci.

+0

Bump. Vous devriez accepter l'une de ces réponses. –

Répondre

1

Remplir le téléchargement nécessite un post complet, et si vous utilisez un panneau de mise à jour, il effectue une publication partielle. Ainsi, FileUpload par lui-même ne fonctionnera pas. Vous devrez le gérer différemment en appelant le RegisterPostBackControl.

Voir ce lien pour plus de détails ->http://geekswithblogs.net/mmintoff/archive/2009/04/01/fileupload-within-updatepanel.aspx

+0

Ok. Comment puis-je enregistrer un bouton dans mon contrôle utilisateur à partir de la page. Je vois que je peux seulement enregistrer le contrôle de trou. Imaginez que le contrôle utilisateur est myUserControl et que le bouton est Enregistrer. Puis-je faire quelque chose comme ScriptManager1.RegisterPostBackControl (myUserControl.Save); Je ne veux pas faire une publication complète chaque fois que l'utilisateur clique sur un bouton de ce contrôle utilisateur. – VansFannel

+0

Ok, ça marche ... la deuxième fois que je clique sur le bouton Enregistrer. Pourquoi? – VansFannel

+0

J'ai mis à jour ma question. Je fais une publication complète, mais FileUpload ne fonctionne pas. – VansFannel

1

En réponse à votre deuxième mise à jour,

J'ai eu ce problème exact, et je crois qu'il a à voir avec le fait que vous ajoutez une dynamique contrôle à votre page à l'intérieur du UpdatePanel.

Il existe peut-être une meilleure façon de le faire, car je ne suis certainement pas un expert ASP.NET, mais j'ai été capable de résoudre ce problème par moi-même en ajoutant le contrôle caché en CSS - avant-c'était nécessaire, puis en incrémentant automatiquement l'ID du contrôle "dummy" afin qu'il n'y ait pas de conflits, et je peux continuer à en ajouter autant que je le souhaite. De cette façon, lorsque le UpdatePanel est déclenché, il reconnaît complètement les contrôles et leur contenu, à l'exception des contrôles cachés bien sûr. J'utilise XSL pour transformer mon XML en une page dynamique qui inclut ASP.commandes NET, donc essentiellement je l'ai fait ce qui suit:

<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> 

Et puis dans le 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 

Je retirai une grande partie du code, mais il faut encore obtenir l'idée générale à travers :)

+0

Merci! Très bonne réponse! – VansFannel

3

Mettez ce qui suit dans votre balise form:

enctype = "multipart/form-data"

1

je devais combiner les deux conseils ici. J'utilise un UpdatePanel pour charger dynamiquement un UserControl et le FileUpload est dans le UserControl. Je devais:

  • RegisterPostBackControl dans le Page_Load de contrôle utilisateur

  • ajouter enctype = "multipart/form-data" à l'élément de forme de la page qui contient le panneau de mise à jour, la page de code. Form.Attributes.Add ("enctype", "multipart/form-data"); n'a pas fonctionné pour moi, il devait être dans l'aspx

Espérons que cela aide.

0

Il a travaillé pour moi, que lorsque je l'ai mis dans le 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 
Questions connexes