Ajax Style File upload for .Net

Ajax Style File upload for .Net

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...
522 views

If you visit Asp.net Ajax Forum, you will find hundreds of request on File Upload Control that it does not give Ajax version of the page when it is placed in an UpdatePanel. Certainly, it is not possible, as the XMLHTTPRequest object that is used internally to post the form does not support file upload. In this post I will show you how to create Ajax like version of the file upload. The trick is very simple, I will use an Iframe to upload the file so the whole page does not get refreshed and when the post is in progress it will show a dummy progress. The following shows you the screenshots of the solutions:

Initial

In Progress
Complete

Now lets discuss the implementation part, starting with the Main page markup.

<fieldset>
    <legend>Photo Upload Demo</legend>
    <div id="divFrame">
        <iframe id="ifrPhoto" onload="initPhotoUpload()" scrolling="no" frameborder="0" hidefocus="true"
style="text-align:center;vertical-align:middle;border-style:none;margin:0px;width:100%;height:55px" src="PhotoUpload.aspx"></iframe>
    </div>
    <div id="divUploadMessage" style="padding-top:4px;display:none"></div>
    <div id="divUploadProgress" style="padding-top:4px;display:none">
        <span style="font-size:smaller">Uploading photo...</span>
        <div>
            <table border="0" cellpadding="0" cellspacing="2" style="width:100%">
                <tbody>
                    <tr>
                        <td id="tdProgress1">&nbsp; &nbsp;</td>
                        <td id="tdProgress2">&nbsp; &nbsp;</td>
                        <td id="tdProgress3">&nbsp; &nbsp;</td>
                        <td id="tdProgress4">&nbsp; &nbsp;</td>
                        <td id="tdProgress5">&nbsp; &nbsp;</td>
                        <td id="tdProgress6">&nbsp; &nbsp;</td>
                        <td id="tdProgress7">&nbsp; &nbsp;</td>
                        <td id="tdProgress8">&nbsp; &nbsp;</td>
                        <td id="tdProgress9">&nbsp; &nbsp;</td>
                        <td id="tdProgress10">&nbsp; &nbsp;</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>
</fieldset>

As you see that we are using few divs to show and hide the upload form and the progress bar. The important thing is we are binding the initPhotoUpload in the frame load event. Now let us check the iframe source page markup.

<form id="photoUpload" enctype="multipart/form-data" runat="server">
    <div>
        <input id="filPhoto" type="file" runat="server"/>
    </div>
    <div id="divUpload" style="padding-top:4px">
        <input id="btnUpload" type="button" value="Upload Photo" />
    </div>
</form>

The iframe source page contains only a file upload control and a button to post the form. Now lets get back to the main page initPhotoUpload function and lets check how it is implemented:

function initPhotoUpload()
{
    _divFrame = document.getElementById('divFrame');
    _divUploadMessage = document.getElementById('divUploadMessage');
    _divUploadProgress = document.getElementById('divUploadProgress');
    _ifrPhoto = document.getElementById('ifrPhoto');

    var btnUpload = _ifrPhoto.contentWindow.document.getElementById('btnUpload');

    btnUpload.onclick = function(event)
    {
        var filPhoto = _ifrPhoto.contentWindow.document.getElementById('filPhoto');

        //Baisic validation for Photo
        _divUploadMessage.style.display = 'none';

        if (filPhoto.value.length == 0)
        {
            _divUploadMessage.innerHTML = '<span style="color:#ff0000">Please specify the file.</span>';
            _divUploadMessage.style.display = '';
            filPhoto.focus();
            return;
        }

        var regExp = /^(([a-zA-Z]:)|(\{2}w+)$?)(\(w[w].*))(.jpg|.JPG|.gif|.GIF|.png|.PNG|.bmp|.BMP)$/;

        if (!regExp.test(filPhoto.value)) //Somehow the expression does not work in Opera
        {
            _divUploadMessage.innerHTML = '<span style="color:#ff0000">Invalid file type. Only supports jpg, gif, png and bmp.</span>';
            _divUploadMessage.style.display = '';
            filPhoto.focus();
            return;
        }

        beginPhotoUploadProgress();
        _ifrPhoto.contentWindow.document.getElementById('photoUpload').submit();
        _divFrame.style.display = 'none';
    }
}

Once the iframe is loaded we are setting few module level variables (All module level variables are prefixed with _ (underscore) character in this example) to DOM elements, we are also getting the reference of the Upload button which is in the iframe and creating its click handler. In the click handler first we are doing few basic validation such as the file upload control is not empty or the file that is specified has a valid image file extension. Once the validation qualifies then we are calling the beginPhotoUploadProgress function (discussed next) and submitting the iframe form. The beginPhotoUploadProgress function is the first of three functions which are used to show the dummy progress bar. Let us see how these functions are written:

function beginPhotoUploadProgress()
{
    _divUploadProgress.style.display = '';
    clearPhotoUploadProgress();
    _photoUploadProgressTimer = setTimeout(updatePhotoUploadProgress, PROGRESS_INTERVAL);
}

function clearPhotoUploadProgress()
{
    for (var i = 1; i < = _maxLoop; i++)
    {
        document.getElementById('tdProgress' + i).style.backgroundColor = 'transparent';
    }

    document.getElementById('tdProgress1').style.backgroundColor = PROGRESS_COLOR;
    _loopCounter = 1;
}

function updatePhotoUploadProgress()
{
    _loopCounter += 1;

    if (_loopCounter <= _maxLoop)
    {
        document.getElementById('tdProgress' + _loopCounter).style.backgroundColor = PROGRESS_COLOR;
    }
    else
    {
        clearPhotoUploadProgress();
    }

    if (_photoUploadProgressTimer)
    {
        clearTimeout(_photoUploadProgressTimer);
    }

    _photoUploadProgressTimer = setTimeout(updatePhotoUploadProgress, PROGRESS_INTERVAL);
}

As we can see we are basically using the timer (window.setTimeout) to show the dummy progress in these functions. Now lets see what happens in the server side when the iframe page posts.

private const string SCRIPT_TEMPLATE = "<" + "script " + "type="text/javascript">window.parent.photoUploadComplete('{0}', {1});" + "< " + "/script" + ">";

private void Page_Load(object sender, EventArgs e)
{
    if (IsPostBack)
    {
        //Sleeping for 10 seconds, fake delay, You should not it try at home.
        System.Threading.Thread.Sleep(10 * 1000);
        UploadPhoto();
    }
}

private void UploadPhoto()
{
    string script = string.Empty;

    if ((filPhoto.PostedFile != null) && (filPhoto.PostedFile.ContentLength > 0))
    {
        if (!IsValidImageFile(filPhoto))
        {
            script = string.Format(SCRIPT_TEMPLATE, "The uploaded file is not a valid image file.", "true");
        }
    }
    else
    {
        script = string.Format(SCRIPT_TEMPLATE, "Please specify a valid file.", "true");
    }

    if (string.IsNullOrEmpty(script))
    {
        //Uploaded file is valid, now we can do whatever we like to do, copying it file system,
        //saving it in db etc.

        //Your Logic goes here

        script = string.Format(SCRIPT_TEMPLATE, "Photo uploaded.", "false");
    }

    //Now inject the script which will fire when the page is refreshed.
    ClientScript.RegisterStartupScript(this.GetType(), "uploadNotify", script);
}

private static bool IsValidImageFile(HtmlInputFile file)
{
    try
    {
        using (Bitmap bmp = new Bitmap(file.PostedFile.InputStream))
        {
            return true;
        }
    }
    catch (ArgumentException)
    {
        //throws exception if not valid image
    }

    return false;
}

In the server side we are first doing some basic validation such as the file upload control has file and the file is a valid image file. Once the validation is done we are injecting some javascript which will be executed when the page is loaded in the browser. The javascript calls the main page photoUploadComplete function which shows the success/failure or the validation message of the upload. Lets see the javascript function photoUploadComplete of the main page.

function photoUploadComplete(message, isError)
{
    clearPhotoUploadProgress();

    if (_photoUploadProgressTimer)
    {
        clearTimeout(_photoUploadProgressTimer);
    }

    _divUploadProgress.style.display = 'none';
    _divUploadMessage.style.display = 'none';
    _divFrame.style.display = '';

    if (message.length)
    {
        var color = (isError) ? '#ff0000' : '#008000';

        _divUploadMessage.innerHTML = '<span style="color:' + color + ';font-weight:bold">' + message + '</span>';
        _divUploadMessage.style.display = '';

        if (isError)
        {
            _ifrPhoto.contentWindow.document.getElementById('filPhoto').focus();
        }
    }
}

The function simply hides the progress bar and shows the upload control then it shows the message in colored text which is sent from the server.

Demo: http://ajaxuploader.com/Demo/simple-upload.aspx

Download: http://www.box.net/shared/d72om3h1g2

Source: http://geekswithblogs.net/rashid/archive/2007/08/01/Create-An-Ajax-Style-File-Upload.aspx

http://www.ajaxupdates.com/wp-content/plugins/sociofluid/images/stumbleupon_32.png http://www.ajaxupdates.com/wp-content/plugins/sociofluid/images/delicious_32.png http://www.ajaxupdates.com/wp-content/plugins/sociofluid/images/blinklist_32.png http://www.ajaxupdates.com/wp-content/plugins/sociofluid/images/furl_32.png http://www.ajaxupdates.com/wp-content/plugins/sociofluid/images/technorati_32.png http://www.ajaxupdates.com/wp-content/plugins/sociofluid/images/magnolia_32.png http://www.ajaxupdates.com/wp-content/plugins/sociofluid/images/google_32.png http://www.ajaxupdates.com/wp-content/plugins/sociofluid/images/myspace_32.png http://www.ajaxupdates.com/wp-content/plugins/sociofluid/images/facebook_32.png http://www.ajaxupdates.com/wp-content/plugins/sociofluid/images/sphinn_32.png http://www.ajaxupdates.com/wp-content/plugins/sociofluid/images/mixx_32.png http://www.ajaxupdates.com/wp-content/plugins/sociofluid/images/twitter_32.png

Related Listings:

  1. Ajax File Upload using JQuery Script that simplifies how you traverse HTML documents, handle events, perform...
  2. Multiple File Upload – JQuery The Multiple File Upload Plugin (jQuery.MultiFile) is a non-obstrusive plugin...
  3. File uploads using ajax Here you can test out the AJAX file upload script....
  4. Asynchronous upload – Like AJAX Here a simple function to asynchronous upload using iframe. Dont...
  5. ASP.NET AJAX File Downloads using IFRAMEs All implemented this functionality in ASP.NET applications at least several...

Do you like this post?

Email:     

Tags: , , , , , , , , , , , , , , , , , , , ,

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URL

Leave a comment



Web Design & CSS (Templates) - TOP.ORG