Uploading Files
A very useful file access feature under ASP.NET is its file upload capability. You can present
a form containing a text box and browse button for users to navigate their local PC directories to
locate a file for uploading. By clicking a button users can copy the local file to
a server directory. This feature is illustrated by creating a file upload form for copying
book pictures to the c:\eCommerce\BookPictures directory. The upload
function is disabled, but you should get a good sense of how it works. The following form
restricts uploads to JPG files no larger that 100 KB.
Picture Upload
Select file:
Figure 10-31. File uploading.
The <asp:FileUpload> Control
File uploading takes place through an <asp:FileUpload>
control. This control produces a textbox along with a "Browse" button for navigating local
computer directories to locate a file for uploading. The general format for this control is
shown below.
Figure 10-32. General format for <asp:FileUpload> control.
The control needs to be accompanied by a button to call a subprogram to copy the selected
file to a server directory and to report on characteristics of the uploaded file. Code
for the above control, its activation button, and its upload message Label is shown below.
<h3>Picture Upload</h3>
<b>Select file: </b>
<asp:FileUpload id="FileUp" Width="300px" Runat="Server"/>
<asp:Button Text="Upload" OnClick="Upload_File" Runat="Server"/><br/>
<br/>
<asp:Label id="Message" Text=" " ForeColor="#FF0000" Runat="Server"
EnableViewState="False"/>
Listing 10-37. Code for file uploading.
File Upload Properties and Methods
An <asp:FileUpload> control has several properties and methods
to manage file uploading. These are listed in Figure 10-33.
Figure 10-33. File upload properties and methods.
Whether or not a file has been selected and appears in the input box is given by the control's
HasFile property. This property returns True
or False for a script to determine whether to proceed with file
uploading.
The FileName property gives the name of the file selected for
uploading. This is a reference only to the file name, not to the entire file path showing in the
input area.
The PostedFile property is a reference to the file
chosen for uploading. This file object's ContentLength property
returns the size of the file in bytes.
The control's SaveAs("path") method writes the
uploaded file to a server directory given by the path string.
The FileName property is appended to this path to copy the file to
the designated directory.
File Upload Scripting
The following script references these properties and methods to upload a picture file to
the "c:\eCommerce\BookPictures\" directory. This subprogram performs
tests on missing file selections, non-JPG file types, and file sizes in addition to uploading
a file.
Sub Upload_File (Src As Object, Args As EventArgs)
If Not FileUp.HasFile Then
'-- Missing file selection
Message.Text = "Please choose a file to upload."
ElseIf InStr(UCase(FileUp.FileName), ".JPG") = 0 Then
'-- Selection of non-JPG file
Message.Text = "You can upload only JPG files."
ElseIf FileUp.PostedFile.ContentLength > 100000 Then
'-- File too large
Message.Text = "Uploaded file size must be less than 100 KB."
Else
'-- File upload
FileUp.SaveAs(Server.MapPath("../BookPictures/") & FileUp.FileName)
Message.Text = "<b>File Uploaded</b><br/>"
Message.Text &= "File Name: " & FileUp.FileName & "<br/>"
Message.Text &= "File Size: " & FileUp.PostedFile.ContentLength & _
" bytes<br/>"
End If
End Sub
Listing 10-38. Script for file uploading.
First, a check is made that a file has been chosen for uploading by testing the
FileUp.HasFile property. If the textbox is empty,
then a message is written to the Message Label and the script ends.
A second check is made to ensure that only JPG files are uploaded. The
FileUp.FileName property is checked to make sure that it contains the substring
".JPG". If not, then a message is written to the
Message control and the script ends. The file name is converted
to upper-case characters for the test to ensure that both ".JPG" and
".jpg" files are accepted.
A third check is made on the size of the upload file as given by its
FileUp.PostedFile.ContentLength property. Files that are larger than 100,000
bytes in length are rejected.
The file is saved to a server directory by appending the FileUp.FileName
property to a directory path in calling the SaveAs() method.
If a file of the same name appears in the directory, it is overwritten.
Managing Picture Files
A useful sidebar to file uploading is giving users the ability to view the file that is uploaded.
This feature is provided in the following example which displays all files in the
c:\eCommerce\BookPictures directory along with a button to delete any of
the picture files.
Contents of BookPictures Directory
Figure 10-34. Picture file display.
Pictures are displayed in an <asp:DataList> control whose code
is shown below.
<asp:DataList id="PictureFiles" Runat="Server"
RepeatColumns="4"
RepeatDirection="Horizontal"
CellPadding="3"
GridLines="Both"
OnItemCommand="Delete_File">
<ItemTemplate>
<asp:Image ImageUrl='<%# "../BookPictures/" & Container.DataItem %>'
Width="45" ImageAlign="Left" Runat="Server"/>
<asp:Label Text='<%# Container.DataItem %>' Runat="Server"/><br/>
<asp:Button Text="Delete" Runat="Server"
Font-Size="7pt"
CommandName='<%# Container.DataItem %>'/>
</ItemTemplate>
</asp:DataList>
Listing 10-39. Code for DataList display of picture files.
Binding Files to a Display Control
Files cannot be bound to a DataList or to other display controls. There is no data source
control for file binding as there is for database binding. An intermediate step is needed, then, to
import file names into a data structure that, in turn, can be bound to the control. A Visual Basic
array is a common way to store file names that can serve as a binding source for a display control.
In the following script that accompanies the example DataList control, a list of file names is
taken from the c:\eCommerce\BookPictures directory and assigned to an array.
This array is then bound to the DataList as properties for the Image, Label, and Button controls
to display and delete these files. This binding is coded in a separate
Bind_Picture_Files subprogram since it takes place on two different occasions. File names
are bound to the control when the page first loads; rebinding takes place after a file is
deleted.
<%@ Import Namespace="System.IO" %>
<SCRIPT Runat="Server">
Sub Page_Load
If Not Page.IsPostBack Then
Bind_Picture_Files
End If
End Sub
Sub Bind_Picture_Files
Dim FileArray() As String
FileArray = Directory.GetFiles(Server.MapPath("../BookPictures"), "*.jpg")
Dim i As Integer
For i = 0 to UBound(FileArray)
FileArray(i) = Replace(FileArray(i), Server.MapPath("../BookPictures/"), "")
Next
PictureFiles.DataSource = FileArray
PictureFiles.DataBind()
End Sub
Sub Delete_File (Src As Object, Args As DataListCommandEventArgs)
File.Delete(Server.MapPath("../BookPictures/") & Args.CommandName)
Bind_Picture_Files
End Sub
</SCRIPT>
Listing 10-40. Script to bind picture files to DataList.
Accessing Directories and Files
In the above Bind_Picture_Files subprogram, an array named
FileArray() is declared and becomes the target for the
Directory.GetFiles() method. This method produces an array of paths to the files in
the BookPictures directory, restricted to files with the
".jpg" extension.
Once an array of data values exists, it can be bound to a display control. In the current example,
however, only the file names are needed, not the full paths appearing in
FileArray(). Therefore, the file paths are converted to file names by iterating the array and
replacing the path portion of the strings with a null character. This iteration produces an array of
file names for all the .jpg files in the
BookPictures directory.
Binding an Array to a Display Control
An array is bound to an output control by assigning it as the DataSource
property of the control and calling the control's DataBind() method. Binding
of array values takes a binding expression in the following format.
Figure 10-35. Binding expression for array values.
The Container.DataItem expression is the array equivalent to the
Eval() and Bind() expressions used in database
binding. For each element in the array, a row is produced in the output control.
In the present example, the 30 elements in FileArray() produce 30
ItemTemplates in the DataList. FileArray() values (picture file names) are
bound to the ImageUrl property of the Image controls, to the
Text property of the Label controls, and to the CommandName property of
the "Delete" Buttons. This ItemTemplate portion of the DataList is repeated in the following listing.
<ItemTemplate>
<asp:Image ImageUrl='<%# "../BookPictures/" & Container.DataItem %>'
Width="45" ImageAlign="Left" Runat="Server"/>
<asp:Label Text='<%# Container.DataItem %>' Runat="Server"/><br/>
<asp:Button Text="Delete" Font-Size="7pt" Runat="Server"
CommandName='<%# Container.DataItem %>'/>
</ItemTemplate>
Listing 10-41. Code to bind picture files to a DataList.
Deleting Picture Files
A DataList, like other bound controls such as a GridView or DetailsView, recognizes Command
events to which subprograms can be attached. Notice in the following partial listing that the DataList
traps for this event with its OnItemCommand event handler which
calls subprogram Delete_Picture when a Command event is triggered. This
event takes place whenever a DataList button is clicked, in this case when the "Delete" Button associated
with a picture is clicked.
Sub Delete_File (Src As Object, Args As DataListCommandEventArgs)
File.Delete(Server.MapPath("../BookPictures/") & Args.CommandName)
Bind_Picture_Files
End Sub
<asp:DataList id="PictureFiles" Runat="Server"
OnItemCommand="Delete_File">
...
Listing 10-42. Code to raise a Command event to call a subprogram to delete a picture file.
The subprogram receives the button's CommandName through its
DataListCommandEventArgs argument list. Since button
CommandNames are the names of picture files, the subprogram receives the name of a file to
delete through its Arg.CommandName argument. This argument is used in the
Directory class' File.Delete() method, supplying the full path to the
file to delete. Since the contents of the BookPictures directory change with
a deletion, the Bind_Picture_Files subprogram is called to re-bind the
directory listing to the DataList.