lbrt.Net

Pinoy Software Engineer

ASP.NET MVC : Multiple file uploads using Uploadify and JQueryUI ProgressBar

I was on a curiosity adventure when I did this one, I wondered whether I could imitate facebook.com multiple photo uploading using ASP.NET MVC. The results where good enough for me to post this on my blog :]. This article would discuss how to create a multiple photo uploader using Uploadify and QueryUI ProgressBar.

First is create an ASP.NET MVC project. Then attach the JQueryUI and Uploadify objects as required. You could download them here.(JQueryUI and Uploadify).

Next is attached the objects in the Site.Master for re usability as shown below:

<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
    <link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
    <%--Uploadify and JQUeryUI--%>
    <link href="<%= Url.Content("~/Scripts/Uploadify/uploadify.css") %>" rel="stylesheet" type="text/css" />
    <link href="<%= Url.Content("~/Scripts/JQueryUI/css/ui-lightness/jquery-ui-1.8.16.custom.css") %>" rel="stylesheet" type="text/css" />

    <script type="text/javascript" src="<%= Url.Content("~/Scripts/jquery-1.6.2.min.js") %>"></script>
    <script type="text/javascript" src="<%= Url.Content("~/Scripts/JQueryUI/js/jquery-ui-1.8.16.custom.min.js") %>"></script>
    <script type="text/javascript" src="<%= Url.Content("~/Scripts/Uploadify/swfobject.js") %>"></script>
    <script type="text/javascript" src="<%= Url.Content("~/Scripts/Uploadify/jquery.uploadify.v2.1.4.min.js") %>"></script>
     <%--End Uploadify and JQUeryUI--%>
    <asp:ContentPlaceHolder ID="JavaScriptContent" runat="server" />
</head>

Next is to create a js script for the home view, I’ve seperated the js from the view to allow separation of js code from the view.

$(document).ready(function () {
    $("#multipleFiles").uploadify({
        'uploader': '/Scripts/Uploadify/uploadify.swf',
        'script': '/Home/Upload',
        'fileDataName': 'file',
        'fileDesc': 'Web Image Files (.JPG, .GIF, .PNG)',
        'fileExt': '*.jpg;*.gif;*.png',
        'buttonText': 'Upload Photos',
        'multi': true,
        'sizeLimit': 1048576,
        'simUploadLimit': 1,
        'cancelImg': '/Scripts/Uploadify/cancel.png',
        'auto': true,
        'height': 30,
        'queueID': 'fileQueue',
        'onError': function (a, b, c, d) {
            if (d.status == 404)
               alert("Could not find upload script. Use a path relative to: " + "<?= getcwd() ?>");
            else if (d.type === "HTTP")
                alert("error " + d.type + ": " + d.status);
            //else if (d.type === "File Size")
            //   alert(c.name + " " + d.type + " Limit: " + Math.round(d.info / (1024 * 1024)) + "MB");
            //else
            //    alert("error " + d.type + ": " + d.text);
        },
        'onComplete': function (event, queueId, fileObj, response, data) {
            //Do Nothing Yet
            var result = $.parseJSON(response);
            $("#progressbar").progressbar("value", result.Percentage);
        },
        'onSelectOnce': function (event, data) {
            $.ajax({
                type: 'POST',
                url: '/Home/SetUploadCount',
                data: { TotalCount: data.filesSelected },
                dataType: 'json',
                success: function (data) {
                },
                error: function (XMLHttpRequest) {
                    var errorMsg = XMLHttpRequest.statusText;
                },
                complete: function (jsonData) {
                }
            });
        }
    });

    $("#progressbar").progressbar();
});  

Then we would re-factor the Home view as shown below, Notice that I’ve created the JavaScriptContent placeholder to hold js reference for page specific js scripts. Also note that you can adjust the visibility of the Uploadify queue by adding the display none style. Don’t forget to add the js you created above on the view.

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Home Page
</asp:Content>

<asp:Content ID="Content3" ContentPlaceHolderID="JavaScriptContent" runat="server">
    <script type="text/javascript" src="<%= Url.Content("../../Scripts/home.js") %>"></script>
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <div style="width: 50%;">
         <input type="file" id="multipleFiles" style="width: 50%;"/><div style="width: 77%;float:right" id="progressbar"></div>
    </div>
    <div id="fileQueue" ></div> <%--style="display:none"--%>
</asp:Content>

Now will add the controller actions used by the Uploadify, note that the method VariousQuality is commented out. I’ve just tested an Image quality compressing approach written here which I’ve used to analyze the effects of compression to an image. Also note that the “/Uploads/” path is missing in the sample solution.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Drawing.Imaging;
using System.IO;
using System.Drawing;

namespace UploadifyTest.Controllers
{
    [HandleError]
    public class HomeController : Controller
    {
        private static float _uploadCount { get; set; }
        private static float _totalCount { get; set; }

        public ActionResult Index()
        {
            return View();
        }

        public JsonResult Upload(HttpPostedFileBase file)
        {
            var uploadFile = file;
            //do business logic here
            //Also try considering compressing the file -> VariousQuality(Image.FromStream(file.InputStream, true, true));

            var percentage = default(float);

            if (_totalCount > 0) 
            {
                _uploadCount += 1;
                percentage = (_uploadCount / _totalCount) * 100;
            }

            return Json(new
            {
                Percentage = percentage
            });
        }

        public JsonResult SetUploadCount(int TotalCount)
        {
            _totalCount = TotalCount;
            _uploadCount = 0;

            return Json(new
            {
                Count = TotalCount
            });
        }

        private void VariousQuality(Image original)
        {
            ImageCodecInfo jpgEncoder = null;
            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
            foreach (ImageCodecInfo codec in codecs)
            {
                if (codec.FormatID == ImageFormat.Jpeg.Guid)
                {
                    jpgEncoder = codec;
                    break;
                }
            }
            
            if (jpgEncoder != null)
            {
                Encoder encoder = Encoder.Quality;
                EncoderParameters encoderParameters = new EncoderParameters(1);

                for (long quality = 10; quality <= 100; quality += 10)
                {
                    EncoderParameter encoderParameter = new EncoderParameter(encoder, quality);
                    encoderParameters.Param[0] = encoderParameter;

                    string fileOut = Path.Combine("/Uploads/", "quality_" + quality + ".jpeg");
                    FileStream ms = new FileStream(fileOut, FileMode.Create, FileAccess.Write);
                    original.Save(ms, jpgEncoder, encoderParameters);
                    ms.Flush();
                    ms.Close();
                }
            }
        }
    }
}

This should be the output:
Before Loading
While Loading
Loading Complete

If you want to download a sample project, below is a link. It is connected to skydrive so you may want to have a hotmail account. Project is created using VS2010.
https://skydrive.live.com/embedicon.aspx/Shared/UploadifyTest.zip?cid=34106e8cbacbd842&sc=documents

Advertisements

11 responses to “ASP.NET MVC : Multiple file uploads using Uploadify and JQueryUI ProgressBar

  1. lobert follower 2011/09/02 at 9:06 PM

    nice one!

  2. sumroo4u 2012/02/09 at 9:44 AM

    can i get zip file of this source code? i am trying download, but it is not wokring

  3. Jenny 2012/04/02 at 12:47 AM

    Where would you place the business logic to upload the file to an entity?
    Not getting any reaction from the upload method using MVC 2 Web Application that I am building

  4. lbrt21 2012/04/02 at 4:21 AM

    Hi Jenny,

    Usually the business logic is within the Upload Method in the controller (e.g. in my exmaple is in the HomeController). Will add a comment there for reference.

    The usual process that I do in saving the upload file to an entity is converting the Inputstream from the HttpPostedFileBase to image -> to byte. Then saving the byte output to a Image data type in an sql serveer table.

    If your not getting any reaction from the upload method, then probably the fault is on the javascript side. Try using tools like fiddler to trace if the method is correctly being called.

    Thanks,
    lbrt

  5. http://batir.tv/maison/index.php?title=Utilisateur:TobyBowen 2013/04/22 at 12:58 AM

    Your style is unique compared to other people I’ve read stuff from. I appreciate you for posting when you have the opportunity, Guess I’ll just bookmark this blog.

  6. Zaveed Abbasi 2013/07/24 at 9:59 AM

    Progress bar is not working, i am not able to cancel photos after uploading them

    • lbrt 2013/07/30 at 6:08 AM

      Hi Zaveed, the progress bar is working fine on my side. Also, I haven’t really covered the other parts such as cancelling and error handling on this blog. This is more of a UI implementation focused article.

      But to answer your inquiry, if the file is already uploaded you can’t cancel it. If the file is uploading in progress you should be able to tick the “X” right beside the uploading photo as per uploadify implementation, if it does not work you can always google for it.

  7. Zaveed Abbasi 2013/07/24 at 10:21 AM

    i am not able to cancel photos after uploading them

  8. ram 2013/11/06 at 6:45 AM

    Hi,
    Its Works like champ in MVC3.
    I had tried the same stuff in MVC 4, i couldn’t accomplish :(…
    Could you update this stuff with MVC4, which supports ayschronous feature.
    Thanks in Advance !!

  9. Pavan 2015/01/06 at 5:38 AM

    Do you have any idea … Uploadify for Jqgrid row…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: