Updated: Click
here for an updated Drag and Drop File upload how to.
Here's a quick AJAX FileUpload written for ASP.NET WebForms that I use every now and then using the old tried and true method of an iframe.
It needs to support several things: It needs to know the directory in which to save the file and it should allow for multiple file upload controls per page. I'll just be putting the basics on this one, nothing too fancy. Plenty of room for customization later on from a UI/UX standpoint.,
Create a new WebForm with the FileUpload control
This will be the page that we end up iframing into whichever page we're adding controls to. It will house the actual FileUpload control and most of the logic.
1. Right click and add a new Web Form. No MasterPage or anything else required.
2. Add the following markup to your new FileUpload.aspx page.
Front-end (quick and painless)
<form id="photoUpload" enctype="multipart/form-data" runat="server">
<div>
<input id="filPhoto" type="file" runat="server"/>
</div>
<div id="divUpload">
<input id="btnUpload" type="button" value="Upload Photo" />
</div>
We should now have just a single file upload control on our page. You can style the control in any which way that you please.
3. For the code-behind, I'm going to do a standard upload using the built in SaveAs method of the FileUpload object.
4. Copy and paste the following into your code behind, and I'll explain along the way.
Code Behind
string strCallback = string.Empty;
protected void Page_Load(object sender, EventArgs e)
{
strCallback = Request["callback"];
if (IsPostBack)
UploadPhoto();
}
This isn't required, but will help us down the line if we ever need to change the callback function that our upload will make once completed.
private void UploadPhoto()
{
// this script will be injected onto our page to notify of completion
string script = string.Empty;
string strFile = string.Empty;
string function = strCallback.Length > 0 ? strCallback : "fileUploadComplete";
string strTemplate = "<script type=\"text/javascript\">window.parent." + function + "('{0}', {1}, '{2}');" + "</script>";
if ((file.PostedFile != null) && (file.PostedFile.ContentLength > 0))
{
string strGuid = Guid.NewGuid().ToString();
strFile = strGuid + Path.GetExtension(file.PostedFile.FileName).ToLower();
file.PostedFile.SaveAs(Server.MapPath("~/images/" + strFile));
}
else
{
script = string.Format(strTemplate, "Please specify a valid file.", "true", "");
}
if (string.IsNullOrEmpty(script))
{
script = string.Format(strTemplate, "Photo uploaded.", "false", strFile);
}
//Now inject the script which will fire when the page is refreshed.
ClientScript.RegisterStartupScript(this.GetType(), "uploadNotify", script);
}
To explain a bit. I'm doing a standard file upload save to the server. And along the away I'm building up a JavaScript 'script' that I will inject onto the page once the post is complete.
So that's it for our web form page. The only thing left is to iframe it onto our client pages. And that will look something like the following.
Usage
<iframe id="iframe1" onload="initFileUpload('iframe1')" scrolling="no" frameborder="0" hidefocus="true"
style="text-align:center;vertical-align:middle;border-style:none;margin:0px;width:100%;height:150px" src='<%=ResolveUrl("~/testing/multifileupload.aspx?callback=callback1") %>'></iframe>
<br />
<iframe id="iframe2" onload="initFileUpload('iframe2')" scrolling="no" frameborder="0" hidefocus="true"
style="text-align:center;vertical-align:middle;border-style:none;margin:0px;width:100%;height:150px" src='<%=ResolveUrl("~/testing/multifileupload.aspx?callback=callback2") %>'></iframe>
5. You can place these on any page, and in any quantity that you'd like.
6. There's one last step. We have to set up the "Upload File" buttons to trigger when they are click. And if you notice the above iframe declarations, they call the initFileUpload function onload, which you can see down below.
function initFileUpload(frame) {
var _ifrPhoto = document.getElementById(frame);
var _divUploadMessage = _ifrPhoto.contentWindow.document.getElementById('uploadmessage');
var btnUpload = _ifrPhoto.contentWindow.document.getElementById('btnUpload');
_divUploadMessage.innerHTML = '';
btnUpload.onclick = function(event) {
var filPhoto = _ifrPhoto.contentWindow.document.getElementById('file');
if (filPhoto.value.length == 0) {
_divUploadMessage.innerHTML = 'Please specify the file.';
filPhoto.focus();
return;
}
_ifrPhoto.contentWindow.document.getElementById('upload_form').submit();
}
}
function callback1(message, isError, image) {
console.log('callback1');
}
function callback2(message, isError, image) {
console.log('callback2');
}
The callback function is set through the querystring parameters in each iframe. It essentially gets carried from your client page, to the iframe, and back to the client page through the injected script.
And for your copy and paste pleasure, feel free to click here.
FileUpload.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="MultiFileUpload.aspx.cs" Inherits="Testing_MultiFileUpload" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<div style="width:50%;margin:0 auto;">
<h1>File Upload</h1>
<form id="upload_form" enctype="multipart/form-data" runat="server">
<div>
<input id="file" type="file" runat="server"/>
</div>
<div id="divUpload">
<input id="btnUpload" type="button" value="Upload File" />
</div>
<div id="uploadmessage"></div>
</form>
</div>
</body>
</html>
FileUpload.aspx (code behind)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
public partial class Testing_MultiFileUpload : System.Web.UI.Page
{
string strCallback = string.Empty;
protected void Page_Load(object sender, EventArgs e)
{
strCallback = Request["callback"];
if (IsPostBack)
UploadPhoto();
}
private void UploadPhoto()
{
string script = string.Empty;
string strFile = string.Empty;
string function = strCallback.Length > 0 ? strCallback : "fileUploadComplete";
string strTemplate = "<script type=\"text/javascript\">window.parent." + function + "('{0}', {1}, '{2}');" + "</script>";
if ((file.PostedFile != null) && (file.PostedFile.ContentLength > 0))
{
string strGuid = Guid.NewGuid().ToString();
strFile = strGuid + Path.GetExtension(file.PostedFile.FileName).ToLower();
file.PostedFile.SaveAs(Server.MapPath("~/images/" + strFile));
}
else
{
script = string.Format(strTemplate, "Please specify a valid file.", "true", "");
}
if (string.IsNullOrEmpty(script))
{
script = string.Format(strTemplate, "Photo uploaded.", "false", strFile);
}
//Now inject the script which will fire when the page is refreshed.
ClientScript.RegisterStartupScript(this.GetType(), "uploadNotify", script);
}
}
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="FileUpload_Client.aspx.cs" Inherits="Testing_FileUpload_Client" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script type="text/javascript">
function initFileUpload(frame) {
var _ifrPhoto = document.getElementById(frame);
var _divUploadMessage = _ifrPhoto.contentWindow.document.getElementById('uploadmessage');
var btnUpload = _ifrPhoto.contentWindow.document.getElementById('btnUpload');
_divUploadMessage.innerHTML = '';
btnUpload.onclick = function(event) {
var filPhoto = _ifrPhoto.contentWindow.document.getElementById('file');
if (filPhoto.value.length == 0) {
_divUploadMessage.innerHTML = '<span>Please specify the file.</span>';
filPhoto.focus();
return;
}
_ifrPhoto.contentWindow.document.getElementById('upload_form').submit();
}
}
function callback1(message, isError, image) {
console.log('callback1');
}
function callback2(message, isError, image) {
console.log('callback2');
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<iframe id="iframe1" onload="initFileUpload('iframe1')" scrolling="no" frameborder="0" hidefocus="true"
style="text-align:center;vertical-align:middle;border-style:none;margin:0px;width:100%;height:150px" src='<%=ResolveUrl("~/testing/multifileupload.aspx?callback=callback1") %>'></iframe>
<br /><br />
<iframe id="iframe2" onload="initFileUpload('iframe2')" scrolling="no" frameborder="0" hidefocus="true"
style="text-align:center;vertical-align:middle;border-style:none;margin:0px;width:100%;height:150px" src='<%=ResolveUrl("~/testing/multifileupload.aspx?callback=callback2") %>'></iframe>
</div>
</form>
</body>
</html>
Walter Guevara is a Computer Scientist, software engineer, startup founder and previous mentor for a coding bootcamp. He has been creating software for the past 20 years.