简体   繁体   中英

ASP FileUpload with secondary iFrame submit only works once per page refresh

My goal is to get an file upload working on my web part using JS, jQuery and an iFrame so as to not require a page refresh. Here is my code

in ASP HTML page

<div class="DocumentUploader" id="DocumentUploader" style="position:relative">
    <div style="position:absolute; top:4px; left:6px"><asp:Literal runat="server" ID="litMultiChoiceDropDocument"></asp:Literal></div>
    <asp:FileUpload runat="server" ClientIDMode="Static" ID="fuMultiChoiceAddDocuments" AllowMultiple="true" onchange="DDPutDocument(); btnMultiChoiceAddDocuments.click()" BorderStyle="None" Width="100%" BackColor="Transparent" Style="padding:0px 0px 0px 0px; opacity:0; cursor:pointer" />
    <asp:Button runat="server" ClientIDMode="Static" ID="btnMultiChoiceAddDocuments" OnClick="btnMultiChoiceAddDocuments_Click" Style="display:none" />
</div>

and in Javascript

var hiddenIFrameID = "hiddenUploader";
function DDPutDocument() {
    var iframe = document.createElement("iframe");
    iframe.id = hiddenIFrameID;
    iframe.style.display = "none";
    document.body.appendChild(iframe);
    document.getElementById("aspnetForm").target = hiddenIFrameID;

    docsRefreshed = false;
    DDRefreshDocuments();
}

var docsRefreshed = false;
function DDRefreshDocuments() {
    if (!docsRefreshed) {
        DDLoadDocuments();
        setTimeout(DDRefreshDocuments, 2500);
    }
    else {
        var iframe = document.getElementById(hiddenIFrameID);
        document.body.removeChild(iframe);
        document.getElementById("aspnetForm").removeAttribute("target");
    }
}

Walkthrough -

The FileUpload onchange event is triggered from the popup file dialog or from a file being dragged onto the FileUpload input. - works

The onchange method calls the javascript method first DDPutDocument and then invokes btnMultiChoiceAddDocuments.click() . - works

The DDPutDocument method creates an iFrame and assigns the target of the first form to be the iFrame, so that a submit action on the form will submit the iFrame, not the form.

The btnMultiChoiceAddDocuments.click() event submits the form, which is actually submitting the iFrame, and some codebehind for the button takes the file and saves it.

The DDRefreshDocuments method is called elsewhere, and it is being called correctly, the else statement in the method also gets called correctly and so should be handling my cleanup.

The problem -

This all works brilliantly for the first instance of uploading a file after the page load, the JS method executes, the button click event triggers a submit on the iFrame and the file is handled by the codebehind. When trying to upload a second file the JS method executes with no errors, carries into an infinite loop with attempting to refresh a list of documents (because the upload didn't work), but does not upload the file. Neither the btnMultiChoiceAddDocuments_Click event or the Page_Load event fire as they did in the first upload instance. The page needs to be reloaded in order to work again.

Ran into this same problem. For me it had to do with the cache. How I fixed it was to return a value from the server after uploading. This will refresh the server code. Or you can set the no-cache to the server back end.

This is my code behind inside a webapi(not sure if youre using a webapi, but you can get some ideas)

public HttpResponseMessage Post([FromUri] FileAttachmentInfo fileAttachmentInfo) { //need to add user credential security here if (Request.Content.IsMimeMultipartContent()) { HttpResponseMessage theResponse = null;

            string filepath = HttpContext.Current.Server.MapPath(ConfigurationManager.AppSettings["DCProfileFilePath"]);
            filepath += fileAttachmentInfo.DCId + "\\" + fileAttachmentInfo.Tab + "\\" + fileAttachmentInfo.Field + "\\" + fileAttachmentInfo.File;                

            //delete previous files and create File Path folder if not already created
            DeleteAndCreateFilePath(filepath);

            MyMultipartFormDataStreamProvider streamProvider = new MyMultipartFormDataStreamProvider(filepath);

            var task = Request.Content.ReadAsMultipartAsync(streamProvider).ContinueWith(t =>
            {
                if (t.IsFaulted || t.IsCanceled)
                    throw new HttpResponseException(HttpStatusCode.InternalServerError);

                var fileInfo = streamProvider.FileData.Select(i =>
                {
                    var info = new FileInfo(i.LocalFileName);
                    //return "File uploaded as " + info.FullName + " (" + info.Length + ")";
                    return info.Name;
                });
                return fileInfo;

            });

            // wait for task to complete. Not really async, is it?!
            task.Wait();
            // remove annoying header 
            theResponse.Content.Headers.Remove("Content-Disposition");
            return theResponse;

        }
        else
        {
            throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "Invalid Request!"));
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM