FileUpload in FormView inside an UpdatePanel
Asked Answered
D

3

5

The Scenario:
I have an ASP.Net webpage which I intend to use for letting the user(not the real users, but content manager basically) insert and edit the records in a table using a FormView. This FormView is inside an UpdatePanel, as I'm also using cascading dropdownlists to let the user select some values.

Now, this FormView also contains 4 FileUpload controls, and as you might know that these fileupload controls require a full postback since most browsers do not let Javascript access the disk. So, this problem would have been solved by doing something like:

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
           <Triggers>
           <asp:PostBackTrigger ControlID="InsertButton" />
           <asp:PostBackTrigger ControlID="UpdateButton" />
           </Triggers>
                    <ContentTemplate>....</ContentTemplate>
</asp:UpdatePanel>

Edit: Forgot to add that the fileuploading takes place in the OnUpdating and OnInserting events of the SqlDataSource.

The Problem:
Since the InsertButton and the UpdateButton reside inside the Formview, I cannot directly access their ID's through markup. And MSDN says that:

Programmatically adding PostBackTrigger controls is not supported.

Please suggest some solution to make this work. Any insight on the matter is highly appreciated. Thanks.

P.S.- A workable solution for me was to set the UpdatePanel's PostBackTrigger as the whole FormView itself:

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
           <Triggers>
           <asp:PostBackTrigger ControlID="FormView1" />
           </Triggers>
                    <ContentTemplate>....</ContentTemplate>
</asp:UpdatePanel>

But now due to a bit of change in requirements, this solution(if you call it a solution) is not acceptable.

Deposit answered 24/8, 2010 at 11:26 Comment(0)
D
3

Yay!! Finally got it to work!

Here's How:

Well contrary to what MSDN says, we can in fact add PostBack Triggers Programmatically. Not necessarily to the UpdatePanel, but to the ScriptManager.

After hours of playing around, here's what worked:

We are not able to access controls inside a FormView, untill the template has been rendered, so we can only add postback triggers after the formview's OnDataBound Event.

protected void FormView1_DataBound(object sender, EventArgs e)
    {
        if (FormView1.CurrentMode == FormViewMode.Edit)
        {
            LinkButton lb = (LinkButton)FormView1.FindControl("UpdateButton");
            ScriptManager.GetCurrent(Page).RegisterPostBackControl(lb);
        }

        //Similarily you can put register the Insert LinkButton as well.
    }

And now, if your UpdatePanel causes ConditionalUpdate, you can do something like this to make it work:

The Markup:

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
           <ContentTemplate>..
            <EditItemTemplate>
              ...
            <asp:LinkButton ID="UpdateButton" runat="server" CausesValidation="True" OnClick="Cause_PostBack"CommandName="Update">Update</asp:LinkButton>
             ...
            </EditItemTemplate>
           ..</ContentTemplate>
</asp:UpdatePanel>

CodeBehind:

//call this function as the OnClick Event Handler for the Controls you want to register as
//triggers.
protected void Cause_PostBack()
    {
        UpdatePanel1.Update();
    }

Otherwise, if your situation allows it(as mine does), just set the UpdatePanel's UpdateMode="Always"

Deposit answered 24/8, 2010 at 13:41 Comment(0)
P
3

Have you given a though about using Iframe for doing the postback ? something like:

<iframe name="uploader" id=uploader 
          src="uploaderSender.aspx?AllowedExtension=<%= AllowedExtension %>&StoringPath=<%= StoringPath %>&StoringFileName=<%= StoringFileName %>&OldFileName=<%= OldFileName %>&MaximumSize=<%= MaximumSize %>"
         width="450" height="50" frameborder=0  scrolling=no >
        </iframe>

with uploaderSender.aspx like :

<form action="UploaderReceiver.aspx" method="post"  enctype="multipart/form-data">
 <input type="file" name="file" id="file"  onchange="document.getElementById('IsFileUploading').style.visibility = 'visible'; document.forms[0].submit()"/>

    <span id="IsFileUploading" style="visibility: hidden">
        <asp:Image ID="Image1" runat="server" ImageUrl="~/immagini/Ajax-loader.gif" />
    </span>
</form>

and UploaderReceiver.aspx like :

protected void Page_Load(object sender, EventArgs e)
        {

            //if there is one file to process
            if (Request.Files.Count > 0)
                //create the folder if it does'nt exists and returns the local path to get it
                string StoringPathToBeSaved = StoringPath.GetFolderPath();

                // append the name of the file to upload to the path.
                            StoringPathToBeSaved = StoringPathToBeSaved + StoringFileName + Extension;

                            Request.Files[0].SaveAs(StoringPathToBeSaved);

        }

this is just bits of code just for you to figure out if you would be interested in this way of dealing with the upload, I can give you more if you want after.

see you, and good luck with your code,

Psilocybin answered 24/8, 2010 at 11:47 Comment(1)
Thanks for your input sir, but actually I currently am sort of a beginner with ASP.Net itself, and have not an iota of an idea about IFrames, and although it would work as you say, but I'm afraid right now I just have to finish this task at hand(and a few others too) in a couple of hours and I guess it would take me some time to learn IFrames and also implement them into my project. Anyways, thanks for your help. +1 to you :)Deposit
D
3

Yay!! Finally got it to work!

Here's How:

Well contrary to what MSDN says, we can in fact add PostBack Triggers Programmatically. Not necessarily to the UpdatePanel, but to the ScriptManager.

After hours of playing around, here's what worked:

We are not able to access controls inside a FormView, untill the template has been rendered, so we can only add postback triggers after the formview's OnDataBound Event.

protected void FormView1_DataBound(object sender, EventArgs e)
    {
        if (FormView1.CurrentMode == FormViewMode.Edit)
        {
            LinkButton lb = (LinkButton)FormView1.FindControl("UpdateButton");
            ScriptManager.GetCurrent(Page).RegisterPostBackControl(lb);
        }

        //Similarily you can put register the Insert LinkButton as well.
    }

And now, if your UpdatePanel causes ConditionalUpdate, you can do something like this to make it work:

The Markup:

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
           <ContentTemplate>..
            <EditItemTemplate>
              ...
            <asp:LinkButton ID="UpdateButton" runat="server" CausesValidation="True" OnClick="Cause_PostBack"CommandName="Update">Update</asp:LinkButton>
             ...
            </EditItemTemplate>
           ..</ContentTemplate>
</asp:UpdatePanel>

CodeBehind:

//call this function as the OnClick Event Handler for the Controls you want to register as
//triggers.
protected void Cause_PostBack()
    {
        UpdatePanel1.Update();
    }

Otherwise, if your situation allows it(as mine does), just set the UpdatePanel's UpdateMode="Always"

Deposit answered 24/8, 2010 at 13:41 Comment(0)
C
0

This is old, but was trying to solve another problem and ran into this. This wasn't my problem, but here's an alternative for anyone new who runs into this as well.

You stated your problem as:

Since the InsertButton and the UpdateButton reside inside the Formview, I cannot directly access their ID's through markup

You actually can access their ID's through markup to use as the ControlID in the PostBackTrigger. You just have to use the button's name that is created in the page html mark-up as the ControlID. You can find the name created by viewing the page source when you're viewing the page in the browser. It typically is the name of the FormView + $ + name of the button.

For example, let's say you have a FormView named "FormView1" that contains an Insert button which you gave the ID of "btnInsert" during design. If you open up your page in the browser to view it live and then view the page's source, you'll notice that the html mark-up of the button will actually be given the name "FormView1$btnInsert".

Use that name as the ControlID in your PostBackTrigger and your update panel will work.

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
       <Triggers>
             <asp:PostBackTrigger ControlID="FormView1$btnInsert" />
       </Triggers>
       <ContentTemplate>....</ContentTemplate>
</asp:UpdatePanel>
Cryptography answered 29/8, 2015 at 0:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.