AsyncFileUpload postback causes double upload

2019-01-15 20:05发布

问题:

I implemented the AsyncFileUpload control on a web page. This web page requires uploaded files to appear in a GridView.
The GridView contains the following columns: "File Name", "Confidential" Check Box, and a "Remove" button to remove the uploaded file.

Since the AsyncFileUpload postback does not do a full page postback, I need to "force" a postback on the OnClientUploadComplete event of the AsyncFileUpload control in order to render the gridview after uploading a file.
In the OnClientUploadCompleteEvent, I use javascript to call __doPostBack. In this postback, I only bind my GridView and display the file information (I don’t re-save the file).

The problem: On the AsyncFileUpload’s first “partial” postback, the file is successfully uploaded, as expected. On the second postback that I force with __doPostBack, the file is re-uploaded.
You can verify this by using Google Chrome, which displays the upload progress. The behaviour is as follows:
- After selecting the file, the progress increments from 0% to 100% and the file is uploaded.
- After this, the __doPostBack executes, and you can see the upload progress increment again from 0% to 100%.

How can I make sure the Gridview is properly populated, but that the file is not uploaded twice?

I attached a sample solution which contains the issue: https://www.yousendit.com/download/MzZFc2ZBNDRrYUN4dnc9PQ

回答1:

Maybe ugly, but works:


1) Add a css-hidden asp:Button bellow the asp:AsyncFileUpload AsyncFileUpload1 control.

<asp:Button runat="server" ID="btnClick" Text="Update grid" style="display:none"/>

2) On the Page_Load method, remove the if (Request.Params.Get("__EVENTTARGET") == "UploadPostback") and put its block in a simple else to the previous if.

3) On the AsyncFileUpload1_UploadedComplete function, also remove the if (Request.Params.Get("__EVENTTARGET") != "UploadPostback") line, but leave intact everything that was inside it.

4) Back to the aspx. Put a asp:UpdatePanel outside the grid GridView1.

<asp:UpdatePanel runat="server" UpdateMode="Conditional">
     <Triggers>
         <asp:AsyncPostBackTrigger ControlID="btnClick" EventName="Click" />
     </Triggers>
     <ContentTemplate>

     <asp:GridView ID="GridView1" ...
     YOUR GRID CODE REMAINS THE SAME
     </asp:GridView>

    </ContentTemplate>
</asp:UpdatePanel>

5) The last step is to change the AjaxUploadComplete client-side javascript function to make it trigger the postback. Replace it with the following:

function AjaxUploadComplete() {
    var btnClick = document.getElementById("btnClick");
    btnClick.click();
}

Any file the user selects is uploaded only once.
All changes here are meant to be made in AjaxUpload.aspx & AjaxUpload.aspx.cs of your AjaxUpload.zip.



回答2:

There is a simpler solution

@@t0x1n3Himself the solution u gave is very simple but does not work

surround the AsyncFileUpload with an update panel name it UpdatePanelAFU then in the UpdatePanelAFU do as the following :

 protected void AsyncFileUpload_UpdatePanelAFU(object sender,AjaxControlToolkit.AsyncFileUploadEventArgs e)
{

    if (Request.Params.Get("__EVENTTARGET") != "UpdatePanelAFU")
        return;
..... rest of the code 
}

enjoy!



回答3:

I believe @Veera had it right. UploadComplete was being called multiple times as the file was uploading. The following worked for me.

void AsyncFileUpload1_UploadedComplete(object sender, AsyncFileUploadEventArgs e) {
    if (AsyncFileUpload1.IsUploading) return;
    // rest of your upload code
}



回答4:

I don't have access to your sample solution which contains the issue but i encounter a double postback too in my project with the AsyncFileUpload component. I found a very simple workaround :

Just add:

private bool justUploaded = false;

Then:

void AsyncFileUpload1_UploadedComplete(object sender, AsyncFileUploadEventArgs e)
{
    if (justUploaded) return;
    justUploaded = true;
    // rest of your upload code
}


回答5:

I find this a more elegant solution, found here: http://forums.asp.net/t/1951566.aspx?AsyncFileUpload+uploads+twice) but below is my altered fully working code:

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>AsyncFileUpload Example</title>
    <script type = "text/javascript">
        function uploadComplete(sender) {
            $get("<%=lblMesg.ClientID%>").innerHTML = "File Uploaded Successfully";
            clearContents();
        }


        function uploadError(sender) {
            $get("<%=lblMesg.ClientID%>").innerHTML = "File upload failed.";
            clearContents();
        }


    function clearContents() {
            var span = $get("<%=AsyncFileUpload1.ClientID%>");
            var txts = span.getElementsByTagName("input");
            for (var i = 0; i < txts.length; i++) {
                if (txts[i].type == "text") {
                    txts[i].value = "";
                }
                if (txts[i].type == "file") {
                    txts[i].value = "";
                }
            }
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>
        <cc1:AsyncFileUpload OnClientUploadError="uploadError"
            OnClientUploadComplete="uploadComplete" runat="server"
            ID="AsyncFileUpload1" Width="400px" UploaderStyle="Modern" EnableViewState = "false"
            UploadingBackColor="#CCFFFF"  ThrobberID="imgLoader" OnUploadedComplete = "FileUploadComplete"
          />
        <asp:Image ID="imgLoader" runat="server" ImageUrl = "~/images/loader.gif" />
        <br />
       <asp:Label ID="lblMesg" runat="server" Text=""></asp:Label>






    </form>
</body>
</html>


回答6:

AsyncFileUpload has a property that named IsUploading. when this property is set to false, a postback will happen. you can check this property like this:

if(AsyncFileUpload1.IsUploading)
 {
  ..... upload codes
 }