Creating a File-Upload User Control with ASP.NET

CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

By Mike Amundsen



This article explains how to create a file-upload user control in ASP.NET. To do this, we’ll build multipart MIME upload forms using the InputFile HTML Server Control and learn how to take advantage of the file-upload services built into the HTTP runtime for ASP.NET. The article will show how to save the uploaded file to disk without granting anonymous users file-write access to folders on your Web server. Finally, you’ll wrap all this in a new ASP.NET user control. This will allow you to add file upload capabilities to almost any Web page quickly and easily.


About the InputFile HTML Server Control and Upload Forms



The key to building an upload feature into your Web site is the InputFile HTML Server Control. This HTML 4.0 compliant control provides users with a standard input box and a Browse button. Pressing this button will call up the user’s local “file open” dialog and allow the user to browse the local workstation (and any connected network drives) to locate and select a file to upload to the target Web server.


The typical ASP.NET syntax for this control is below:


<input type=”file” id=”filename” runat=”server” />


Along with the InputFile control, you also need to make adjustments to the standard HTML FORM control in order to enable file uploads. Setting the ENCTYPE attribute of the form to support multipart MIME data uploads accomplishes this task. The HTML block below shows both the InputFile and the modified HTML FORM in ASP.NET:



<form enctype=”multipart/form-data” runat=”server”>
<input type=”file” id=”filename” runat=”server” />

</form>



NOTE: The only thing ASP.NET-ish about the above code is the use of the “runat=sever” attributes that allow server-side coding of HTML controls. The rest of the code above is pure HTML 4.0 and will work in most standard browsers.



Creating the File-Upload User Control




Now that you know the basics of creating an upload form using HTML 4.0 features, it’s time to start building the ASP.NET user control. The first step is to create a file to hold the user control and add an ASP.NET declaration line to the page.


NOTE: Since user control support is rather limited in the current beta release of Visual Studio.NET, all the code examples here will be built with a simple editor instead. Hopefully, the final release of VS.NET will provide a friendlier environment for creating and using ASP.NET user controls.


To create your file upload user control, add a blank file called “fileUpload.ascx” to an existing Web. The ASCX extension is important. This tells the ASP.NET runtime environment that you are creating a user control, not a standard ASP.NET Web page.


After you create the new file, add the following ASP.NET declaration as the first line in the document. This declaration line helps the ASP.NET runtime compiler know how to compile the page.


<%@control description=”ASP.NET file upload user control”%>


Just by creating a file with an ASCX extension and adding this simple declaration line, you have created a complete user control. It doesn’t do anything yet, but at least it’s a start!


Adding the Upload Form to the User Control




Now that you have a user control started, you’re ready to add HTML markup to the page to allow users to select a file from their workstation and upload it to your Web server. For this example, you’ll create a form with two inputs, one label display and a single button. You’ll also add three prompts to the page to help users know how to use the form. Finally, you’ll wrap all this in a table to help control the layout as well as the special HTML FORM tag needed to enable file uploads from users’ browsers.


First, enter the form and table markup for the inputs. This will define the input space on the form and indicate the form should allow uploads. The table will have two columns and four rows. An example follows:


<form enctype=”multipart/form-data” runat=”server”>
<table width=”400″ cellpadding=”4″ bgcolor=”silver”>
<tr>

<td valign=”top” width=”100″>
</td>
<td valign=”top” >
</td>
</tr>
<tr>

<td valign=”top” >
</td>
<td valign=”top” >
</td>
</tr>
<tr>

<td valign=”top” >
</td>
<td valign=”top” >
</td>
</tr>
<tr>

<td valign=”top” >
</td>
<td valign=”top” >
</td>
</tr>
</table>

</form>



You’ll notice the use of additional attributes in the table markup to control alignment, width, cell spacing, and coloring for the table. None of this is required to make the form function, but adds to the look of the user control. Again, notice the use of the ENCTYPE attribute on the HTML FORM element. This is the magic that will allow the browser to send a file to the Web server.


The next step is to add three HTML span elements to hold the input prompts for the form. Using these spans will allow you to customize or localize the user control in the future. Below is the HTML TABLE with the span controls added. Notice that each control has the “runat=server” attribute to allow easy server-side coding later.


<form enctype=”multipart/form-data” runat=”server”>
<table width=”400″ cellpadding=”4″ bgcolor=”silver”>
<tr>

<td valign=”top” width=”100″>
<span id=”upSpan” runat=”server”/>
</td>
<td valign=”top” >
</td>
</tr>

<tr>
<td valign=”top” >
<span id=”saveSpan” runat=”server”/>
</td>
<td valign=”top” >
</td>

</tr>
<tr>
<td valign=”top” >
<span id=”statusSpan” runat=”server”/>
</td>
<td valign=”top” >

</td>
</tr>
<tr>
<td valign=”top” >
 
</td>

<td valign=”top” >
</td>
</tr>
</table>
</form>



Now, you need to add the two HTML input elements and another span element to hold the status message display. Be sure to include the “runat=server” attribute for all the controls so you can easily program against them using ASP.NET server-side code.



<form enctype=”multipart/form-data” runat=”server”>
<table width=”400″ cellpadding=”4″ bgcolor=”silver”>
<tr>
<td valign=”top” width=”100″>
<span id=”upSpan” runat=”server”/>
</td>

<td valign=”top” >
<input type=”file”
id=”filename” runat=”server” />
</td>
</tr>
<tr>
<td valign=”top” >

<span id=”saveSpan” runat=”server”/>
</td>
<td valign=”top” >
<input type=”text”
id=”savename” runat=”server” />
</td>
</tr>

<tr>
<td valign=”top” >
<span id=”statusSpan” runat=”server”/>
</td>
<td valign=”top” >
<span id=”status” runat=”server” />

</td>
</tr>
<tr>
<td valign=”top” >
 
</td>

<td valign=”top” >
</td>
</tr>
</table>
</form>



Finally, you need to add a button to the form to allow users to post the data back to the Web server. Along with the usual attributes, also add the OnServerClick attribute to register a server-side event handler. This event handler will perform the actual uploading of the file to the Web server. Below is the markup for the HTML button. Add this code to the last <td> element of the table.



<input type=button id=”uploadBtn”
OnServerClick=”uploadBtn_Click” runat=”server” />


That completes the HTML markup for the user control. In the next section, you’ll add the server-side execution code to allow setting the control prompts and execute the actual file upload.



Adding Sever-Side Code to the User Control



For this sample, you’ll be able to set the input prompts, the default upload target folder, and the button label at runtime. This will make is easy to customize the user control on the fly. To accomplish this, first add a single server-side script block to the user control. Then declare the various attributes as public variables. You’ll also set default values for all the attributes to make it easy to create a standard upload control.


Below is the start of the code block. Add this block immediately following the <%@…%> declaration at the top of the user control page.



<script language=”c#” runat=”server”>

// public attributes for the user control
public string uploadText=”Upload file:”;
public string saveText=”Save as:”;
public string statusText=”Status:”;
public string submitText=”Upload File”;
public string uploadFolder=”c:\\temp\\”;

</script>



NOTE: This code example was written in C#. However you could also write the server-side code in VB.NET or JScript.NET.


Next, you need to add code for the Page_Load event. In this event, you’ll set the various prompt spans and the button text using the public variables you declared in the previous step. Below is the code to handle the Page_Load event.


private void Page_Load(object o, EventArgs e) {

// move attributes into the form
upSpan.InnerText=uploadText;
saveSpan.InnerText=saveText;
statusSpan.InnerText=statusText;
uploadBtn.Value=submitText;
}



Finally, you need to add the event handler for the button click. This is the code that does the actual uploading of the file. Actually, there is very little code needed to do this. In fact, you can accomplish the task in a single line of code, as follows:


filename.PostedFile.SaveAs(sPath+savename.Value);


This line uses the name of the control (filename) and accesses the PostedFile object’s SaveAs method to pass the path and filename of the file to save. However, to make the control a bit more robust, you’ll add some server-side content checking and then some code to pull the actual file size, type, and location from the PostedFile object. Finally, you’ll wrap the call to the SaveAs method in a try…catch block and display an appropriate status message based on the results.


All this code goes in the uploadBtn_Click method referred to in the OnServerClick attribute of the button control. Below is the complete code block for the event handler.


private void uploadBtn_Click(object o, EventArgs e) {

// make sure there is a file to upload
if (savename.Value == “”) {
status.InnerHtml = “Missing a ‘save as’ name.”;
return;
}

// try save the file to the web server
if (filename.PostedFile != null) {
string sPath=uploadFolder;

//build file info for display
string sFileInfo =
“<br>FileName: “+
filename.PostedFile.FileName+
“<br>ContentType: “+
filename.PostedFile.ContentType+
“<br>ContentLength: “+
filename.PostedFile.ContentLength.ToString();

try {
filename.PostedFile.SaveAs(sPath+savename.Value);
status.InnerHtml = “File uploaded successfully.”+
sFileInfo;
}
catch (Exception exc) {
status.InnerHtml = “Error saving file”+
sFileInfo+”<br>”+e.ToString();
}
}
}



After you enter this last bit of code, save the file (uploadfile.ascx) to your Web. Now you’re ready to create a simple ASPX test page to see how the control works.


Testing the File-Upload User Control in an ASP.NET Page




Since the user control is completed and saved to your Web, you can add a new ASPX page to the same Web and test out the UploadFile user control. First, create a new blank file in the Web called “UploadTest.aspx.”


Next, add the code below to the page. This is the basic HTML markup for the page. After you add this, you’ll add a declaration to register the user control and an instance of the user control in the body of the page.


<html>
<head>
</head>

<body>
<h2>File Upload User Control Sample</h2>
<hr />

</body>
</html>



Now you’re ready to add the user control to the page. First, add a declaration at the top of the page that registers the user control for use on this page. You’ll need to define the tagprefix and tagname to use for the control, as well as the actual location of the ASCX file that holds the code for the control.

Below is the complete register declaration. Add this line at the top of the document. It needs to be the very first line in the file.


<%@ register tagprefix=”era”
tagname=”upload”
src=”fileUpload.ascx” %>


Finally, you need to add an instance of the user control to the body of the HTML document. The simplest version of the user control would be:


<era:upload runat=”server”/>


By just adding this to the page, you’ll be able to save and run the document. However, you can also set any of the public attributes within the control or in the Page_Load script block in the ASPX document. For example, to set the attributes within the control, you could use the following HTML markup:

<era:upload runat=”server”
submitText=”Send File”
uploadFolder=Server.MapPath(“//”)
/>



If you wanted to use server-side code to set the properties, you could add code to the Page_Load event like this:


<script language=”vb” runat=”server”>

sub Page_Load(o as object, e as EventArgs)

myControl.submitText=”Send File”
myControl.uploadFolder=Server.MapPath(“//”)

end sub

</script>



When you actually run the test page you can select a file, set the “SaveAs” name, and press the button to send the file to the server. If you’re successful, you’ll see a message like the one in the screenshot below.


Figure 1



External Components and File Rights




Unlike performing file uploads in ASP 3.0, you did not need to use an external COM component to handle the file upload. That’s because the upload services are built into the ASP.NET runtime. Once you start building your ASP.NET applications, you won’t need a third-party file-upload component anymore!


Also, you probably realized that you did not need to set some folder to allow anonymous users’ create and write rights. Again, the ASP.NET runtime has the smarts to save the file to any folder on the server you designate without requiring you to grant create and write rights to the user. This means you can safely add file-upload services to your Web site without weakening security on your Web server.


And all this happens for free when you use ASP.NET!



About the Author




An internationally known author and lecturer, Mike Amundsen travels throughout the United States and Europe speaking and teaching on a wide range of topics, including .NET, the Internet, team development and leadership, and other subjects. He has more than a dozen books to his credit. His most popular titles are Sams Teach Yourself Database Programming with Visual Basic in 21 Days, 3rd Ed., and Using Visual Interdev 6. Mike is currently working on a new book covering Web development using Microsoft’s .NET Framework.


When he is not working, Mike spends time with his wife and three children at their home in Kentucky. He can be reached at [email protected].


More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read