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:



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
nice one!
can i get zip file of this source code? i am trying download, but it is not wokring
Hi sumroo,
I’ve updated the download link. check it out.
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
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
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.
Progress bar is not working, i am not able to cancel photos after uploading them
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.
i am not able to cancel photos after uploading them
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 !!
Do you have any idea … Uploadify for Jqgrid row…