NOTE 23 Oct 2012
Uploadify is ace for performing file upload and image upload, but ASP.NET MVC docs were lacking, so I hope this helps someone. Critical points addressed here include:
- Uploadify flash upload button is ugly so we use CSS to make it invisible and fake an HTML button under it.
- The Uploadify flash upload doesn't pass the ASP.NET session and authentication cookies naturally, which we want for recognition and authorization, so we handle that.
UPLOADIFY FILES
Put all Uploadify files in a project folder called
ClientScript/uploadify
SCRIPT
Put this code on the regular View page that performs the upload.
<script type="text/javascript" src="<%= Url.Content("~/ClientScript/jquery-1.4.2.min.js") %>"></script>
<script type="text/javascript" src="<%= Url.Content("~/ClientScript/uploadify/swfobject.js") %>"></script>
<script type="text/javascript" src="<%= Url.Content("~/ClientScript/uploadify/jquery.uploadify.v2.1.4.min.js") %>"></script>
<script type="text/javascript">
$(function () {
// Uploadify File Upload System
// SessionSync data is sent in scriptData for security reasons, see UploadifySessionSync() in global.asax
var UploadifyAuthCookie = '<% = Request.Cookies[FormsAuthentication.FormsCookieName] == null ? string.Empty : Request.Cookies[FormsAuthentication.FormsCookieName].Value %>';
var UploadifySessionId = '<%= Session.SessionID %>';
$("#fuFileUploader").uploadify({
'hideButton' : true, // We use a trick below to overlay a fake html upload button with this hidden flash button
'wmode' : 'transparent',
'uploader': '<%= Url.Content("~/ClientScript/uploadify/uploadify.swf") %>',
'cancelImg': '<%= Url.Content("~/ClientScript/uploadify/cancel.png") %>',
'buttonText': 'Upload File',
'script': '<%= Url.Action("FileUpload", "Media") %>',
'multi': true,
'auto': true,
'scriptData' : { RequireUploadifySessionSync: true, SecurityToken: UploadifyAuthCookie, SessionId: UploadifySessionId },
'onComplete' : function (event, ID, fileObj, response, data)
{
response = $.parseJSON(response);
if (response.Status == 'OK')
{
// Put your own handler code here instead of the following...
alert('File Uploaded OK!');
}
}
});
});
</script>
HTML
Put this HTML on the same View as the script above.
<div style="position: relative;">
<input type="button" id="btnUpload" value="Upload File" />
<div style="position: absolute; top: 4px; left: 3px;">
<input id="fuFileUploader" name="file_upload" type="file" />
</div>
</div>
GLOBAL.ASAX
Add the following bits.
protected void Application_BeginRequest(Object sender, EventArgs e)
{
if (HttpContext.Current.Request["RequireUploadifySessionSync"] != null)
UploadifySessionSync();
}
/// <summary>
/// Uploadify uses a Flash object to upload files. This method retrieves and hydrates Auth and Session objects when the Uploadify Flash is calling.
/// </summary>
/// <remarks>
/// Kudos: http://geekswithblogs.net/apopovsky/archive/2009/05/06/working-around-flash-cookie-bug-in-asp.net-mvc.aspx
/// More kudos: http://stackoverflow.com/questions/1729179/uploadify-session-and-authentication-with-asp-net-mvc
/// </remarks>
protected void UploadifySessionSync()
{
try
{
string session_param_name = "SessionId";
string session_cookie_name = "ASP.NET_SessionId";
if (HttpContext.Current.Request[session_param_name] != null)
UploadifyUpdateCookie(session_cookie_name, HttpContext.Current.Request.Form[session_param_name]);
}
catch {}
try
{
string auth_param_name = "SecurityToken";
string auth_cookie_name = FormsAuthentication.FormsCookieName;
if (HttpContext.Current.Request[auth_param_name] != null)
UploadifyUpdateCookie(auth_cookie_name, HttpContext.Current.Request.Form[auth_param_name]);
}
catch {}
}
private void UploadifyUpdateCookie(string cookie_name, string cookie_value)
{
HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(cookie_name);
if (cookie == null)
cookie = new HttpCookie(cookie_name);
cookie.Value = cookie_value;
HttpContext.Current.Request.Cookies.Set(cookie);
}
Models/MediaAssetUploadModel.cs
public class MediaAssetUploadModel
{
public HttpPostedFileBase fileData { get; set; }
public string SecurityToken { get; set; }
public string Filename { get; set; }
}
Controllers/MediaController.cs
[Authorize]
public ActionResult FileUpload(MediaAssetUploadModel uploadedFileMeta)
{
string fullFilePath = SaveUploadedFile(uploadedFileMeta);
//TODO: Error handling
return Json(new { Status = "OK" });
}
//TODO: move this into a manager/repository class
private string SaveUploadedFile(MediaAssetUploadModel uploadedFileMeta)
{
string fileName = Guid.NewGuid() + System.IO.Path.GetExtension(uploadedFileMeta.Filename);
string fullSavePath = Path.Combine(ConfigurationManager.AppSettings["MediaAssetFolder"], fileName);
uploadedFileMeta.fileData.SaveAs(fullSavePath);
return fullSavePath;
}
Web.config
Make following changes to upload files to
c:\temp , with a max file size of 100Mb.
Change these to suit yourself -
c:\temp will get automatically cleared so you have been warned.
If you create your own upload folder, remember you will need to give write perms to the ASP.NET process.
<configuration>
<appSettings>
<add key="MediaAssetFolder" value="c:\temp"/>
</appSettings>
<system.web>
<httpRuntime maxRequestLength="100000" />
</system.web>
</configuration>