Async File Uploading using Asp.Net

Async File Uploading using Asp.Net

Recently I ran into an issue, that by the looks of Google, is affecting many others too.  I wanted to be able to allow users to select an upload path, using the standard Asp.Net fileUpload control, and maintain that control’s path through postbacks, so I could perform some server side validation.  As far as I can tell, this is impossible.  It is also only possible to get the control’s path, programatically when a full postback occurs and for security reasons, the control does not allow its path to be programatically set, so storing the path prior to the postback and restoring it, is not an option either.   So what this means is there is no way to accomplish what I needed to do using the standard fileUpload control.

Recently the AjaxControlToolkit has introduced a new control, the AsyncFileUpload control. http://www.asp.net/ajax/ajaxcontroltoolkit/Samples/AsyncFileUpload/AsyncFileUpload.aspx

This control can be set up to look identical to the standard fileUpload control, but immediately performs a file upload once the user selects their file path. This allows async file uploading! Problem solved! ….. well…..sorta

I also wanted a way to disable all other asyncFileUpload controls on a page while an upload is in progress, this was preventing an “Unknown Server Error” browser alert message when trying to perform 2 async uploads at once. I google’d and google’d for this problem, and could not find anyone who was having a similar issue, or a fix for it, so I had to go for a work around.

In a nutshell, I implemented the client-side uploadStarted, and uploadCompleted events on the AsyncFileUpload control, and used some Jquery within those to disable specific controls using css classes. Problem with this was that once an AsyncFileUpload control is disabled, its file path can no longer be read server-side until the page is refreshed again.  I am not sure if this is a bug, or is by design, but never the less, it was not working properly, and time was not on my side.

So I had to develop another workaround…

I decided I could show the user a button and textbox that was rigged to look JUST like a file upload control. I could populate the textbox with the fileUpload control’s path, and they would never know the difference….hopefully.

After a long battle with the fileUpload controls, I managed to get a fairly suitable workaround…. when a file starts uploading, the “fake” file upload control appears, and when the file is done uploading, the real one comes back.

Let’s start with the code:

In the code behind you can register the script as a client script block, in the Page_Load or somewhere similar.  Wherever you prefer, just so that it is included on the rendered page. The code I used, is below.  It uses Jquery to find elements based on their css class, and to hide all AsyncFileUploads on the page once an upload starts and then bring those back when the upload is complete along with populating our “fake” fileupload with the file upload path that is used, to make it all look like its a real file upload control that is just disabled.  Confusing? It’s not too bad, it’s just hard to explain:

private void SetJavaScript()
{
    /*
        * All this Javascript basically hides/shows/populates a
        * fake file upload control (button and textbox), that is displayed when
        * a file is being uploaded
        * This lets a user only upload one file at a time, and
        * prevents errors from the AsyncFileUpload control
        * */

    ScriptManager.RegisterClientScriptBlock(this.Page,typeof(Page), "UploadJS",

        @"

            function UploadStarted(sender, args)
            {
            disableAllUploads();
            }

            function disableAllUploads()
            {
            $('.asyncFileUpload').hide();
            $('.fakeAsyncFileUpload').show();
            }

            function enableAllUploads()
            {
                $('.asyncFileUpload').show();
                $('.fakeAsyncFileUpload').hide();

                $('.asyncParent input[type=file]').each(
                    function()
                    {
                        $(this).parents('.asyncParent')
                        .find('.fakeAsyncFileUploadText').val(this.value);
                    });
            }

        function UploadComplete(sender, args)
        {
            enableAllUploads();
        }"

        , true);
}

Here is what the ASPX looks like
(this is where the CSS classes are listed, and will make sense in the context of the JavaScript above:

<asp:Panel ID="pnlFile" runat="server" Visible="false" Width="325">
    <div class="asyncParent">
        <div class="fakeAsyncFileUpload" style="display: none;">
            <asp:TextBox ID="fakeTxt" CssClass="fakeAsyncFileUploadText" Width="207"
            runat="server"
                Enabled="false" />
            <asp:Button ID="fakeBtn" runat="server" Enabled="false" Text="Browse" />
            <asp:Image ID="throbberImg" runat="server" ImageUrl="~/images/indicator.gif"
            Style="position: relative;
                left: 2px; top: 4px;" />
        </div>
        <ajaxtoolkit:asyncfileupload id="btnFileUpload" cssclass="asyncFileUpload"
            onclientuploadcomplete="UploadComplete" onclientuploadstarted="UploadStarted"
            persistfile="true" runat="server" width="280" errorbackcolor="White"
            throbberid="throbberImg"
            completebackcolor="White" />
    </div>
</asp:Panel>

As you can see, each control has its own style for a purpose. That way they can easily be hidden/shown using Jquery
and client-side events of the AsyncFileUpload control.

This was my workaround to the whole “fileUpload control clearing on postback issue. Hopefully it can benefit others who were having the same problem I was.

Share Your Thoughts!

Testimonials

What My Clients Say

Karin - Hope and Future

Brent has always been very prompt and generally exceeds our expectations with his work. His maintenance fee is very reasonable. I strongly recommend him!  We get many compliments on our beautiful web site!

Dan

I contacted Krueger Web Design and Brent did everything.  He setup a test site with the changes so we could verify everything was correct before we transferred from my old hosting provider.  During the setup and conversion Brent was extremely professional and responsive. He responded to any issues the same day.

Dan Kaufman
Emily - GFCLT

We've had a great experience working with Krueger Web Design. Prompt responses, great ideas, effective work... all at a reasonable price! This was the perfect fit for our organization.

Mahmud - ACMC

I would love to recommend you to anyone! You have been very helpful when we needed you the most.

Brian - SEMNIC

Working with Krueger Web Design was effortless. Communicating what I wanted for the website and the results that I saw were identical. The customer service was always prompt and I am completely satisfied with the product.

Zach - Stadium Club

Exactly what I wanted! Fast turnaround time and very affordable. Answered all of our questions quickly and made adjustments promptly. Very easy to work with and puts everything into terminology that even I can understand!

Contact Krueger Web Design

Have a question for me? Need an estimate on some work? You can email me at brent@kruegerwebdesign.com or drop me a line using the button below:

Copyright © 2017 Krueger Web Design - All rights reserved
Web Design in Madison, WI