Displaying Files and Folders in a GridViewBy Scott Mitchell
The .NET Framework provides a variety of classes in the
System.IOnamespace that simplify working with the file system. Using these classes it's possible to delete files and folders, to create new files, to edit existing files, and more. These classes, combined with ASP.NET's suite of Web controls and databinding syntax, make it quite easy to present information about the files on the web server's file system to visitors to your website. With a bit of markup and code, it's possible to add a simple file browser to a web page that allows users to view the files and folders from a particular directory on the web server. Such file browsers are useful if you let users upload content to the website and need to let them view their uploaded content. If you have a folder that contains user-accessible content like images, PDF files and Word documents, a file browser offers a quick and easy way for users to see what content is available and to view content of interest.
Back in 2003 I wrote an article titled Displaying the Files in a Directory using a DataGrid that showed how to list the files of a particular folder in a DataGrid Web control. This dated article still attracts a decent amount of traffic and questions from readers, so much so that I thought it worthwhile to update the content to use the latest technology, namely ASP.NET 4 and the GridView Web control. I also added some new features. For example, the file browser now lists both files and folders, allowing users to view the files in subfolders. Also, I moved the markup and code into a User Control, which simplifies adding the file browser to an ASP.NET page. This article walks through this new, updated version; the complete, working code is available for download at the end of this article. Read on to learn more!
First Things First: A Quick Overview of the File Browser
Before we get started with examining the guts of the new file browser, let's take a moment to discuss what it is we're trying to accomplish. An online file browser is a user interface on a web page through which the visitor can explore the contents of a particular directory on the web server's file system. The directory of interest can be a directory within the web application or a directory outside of the web root. For instance, if the web server is rooted at the folder
C:\Sites\MySite, the file browser could be used to display the contents in a particular folder within the web application, such as
C:\Sites\MySite\Content, or it could be used to display the contents of a folder outside of the web application's "space", such as
The screen shot to the right shows what the file browser I've created looks like when pointed to a directory with three folders named
and a number of files, including
Flowers.jpg, among others. Much like Windows Explorer, the grid
displays the name of each file and folder, its type, the date modified, and (for files) its size.
Clicking on a folder causes a postback. On postback, the grid is repopulated with the contents of the selected folder's files and subfolders. When using the file browser
to view the contents of a folder outside of the web application root the files are listed as text. When the file browser points to a folder within the web application
then the file names are displayed as hyperlinks to the actual file. For example, if the grid to the right was configured to display the contents in the
folder then clicking the
f1040ez.pdf file in the grid to the right would send the user to
would display the PDF file in the user's browser.
Adding the File Browser to an Existing Web Page
The file browser I created is implemented as a User Control, which simplifies adding the file browser to an ASP.NET page. To add the file browser to a page on your website, start by downloading the complete code at the end of this article. The download includes the User Control in both VB and C#, along with a working demo. I encourage you to try out the demo and get familiar with the User Control's usage and functionality before attempting to add it to your website.
Once you are ready to add the User Control to your website, copy the appropriate code and markup files from the sample application's
~/UserControls folder to
your web application. (Specifically, if your application is in C# then copy the
FileGridCS.ascx.cs files; if you use Visual
Basic, copy the
FileGridVB.ascx.vb files.) Also copy the
~/Images/folder.png image from the sample application to
~/Images folder in your application, as this image is used by the User Control to show the folder icon next to folder names. Finally, you'll need
to include the
FileSystemItem class in your project, which is defined in a class file in the
App_Code folder. If you are using a Web Site Project,
you can simply copy the C# or VB file into your application's
App_Code folder. If you are using a Web Application Project, add the appropriate class file
to your project in any folder (such as a folder named
Classes), but for reasons that are beyond the scope of this article, do not name that folder
Now, open the ASP.NET page that is to include the file browser and go to the Design view. Then, from the Solution Explorer, drag the User Control onto the Design surface. Doing this adds two bits of markup to your ASP.NET page:
@Registerdirective that registers the User Control. This will similar to the following:
<%@ Register src="UserControls/FileGridCS.ascx" tagname="FileGridVB" tagprefix="uc1" %>
- The markup for the User Control, which will look something like the following:
<uc1:FileGridVB ID="FileGridCS1" runat="server" />
HomeFolderproperty. If this directory is a folder within the web application then specify the directory using the tilde character (
~) like so:
~/DirectoryName. If this directory is outside of the web application then specify the directory name using the fully qualified path, like so:
By default, the file browser displays all of the folders and files in the specified directory on the screen. If you want to only display a certain number of folders and
files at a time then set the User Control's
PageSize property to the number of folders or files to show per page. (The grid in the screen shot above has
PageSize property set to 10.) After setting the
HomeFolder property and (optionally) the
PageSize property, your User Control's
markup should look similar to the following:
After setting (at minimum) the
HomeFolder property, take a moment to view your ASP.NET page. At this point you should see a grid that lists the folders (if any)
and files in the specified directory. If the directory is a folder within the web application then the files should be clickable, and clicking a file should display it
in the browser. Clicking on a folder name triggers a postback and on refresh the contents of that folder are displayed. The screen shot below shows the file browser
after clicking the folder name
Old - this lists the files and folders in the
~/Content/Old folder. Note the folder named
When clicked, the
.. folder returns the visitor to the parent directory. Also note that the listing in the screen shot below includes an additional folder,
For Alice; clicking that folder name would display the contents of the
~/Contents/Old/For Alice folder.
At this point we've covered how to add the file browser to an existing ASP.NET page, but we've yet to explore how the User Control works behind the scenes. The remainder of this article examines some of the more interesting and educational aspects of the file browser control and is worth reading if you plan on extending or enhancing the file browser User Control or if you just want to learn more about how to work with the file system in an ASP.NET application.
Getting Information About the Files and Folders in a Specified Directory
The file browser User Control uses the
DirectoryInfoclass to retrieve the list of files and folders in the folder of interest. To use the
DirectoryInfoclass we start by specifying the path to the directory whose information we are interested in. The User Control has a property,
CurrentFolder, that returns the path to the folder whose items are to be displayed. Initially, the User Control's
CurrentFolderproperty is equal to its
HomeFolderproperty, but the
CurrentFolderproperty is reassigned if the user clicks on a folder name (more on that later).
The GridView is populated programmatically whenever the
PopulateGrid method is called. Let's delve into this method's code... (Note: I've left out some of
the code in the
PopulateGrid method to focus on the more germane parts.)
Once we have a DirectoryInfo object, we can use the
GetFiles methods to get information about the directory's subfolders and files.
GetDirectories method returns an array of
DirectoryInfo objects; the
GetFiles method returns an array of
FileInfo objects. The
classes have properties that provide information about each folder or file, including the name of the file/folder, the last access date, the creation date, and so on.
In order to show the set of subfolders and the set of files in a single GridView control we need to combine them into a common type. (You cannot bind heterogeneous types
in a databound control.) To this end, I created a new class named
FileSystemItem - well, actually, one named
FileSystemItemCS and one named
FileSystemItemVB, which are C# and VB versions, respectively. In a nutshell, the
PopulateGrid method gets the folders and files in the requested
directory and then loops through those, creating a
FileSystemItem object for each folder and file. This collection of
FileSystemItem objects is
then what is bound to the GridView.
FileSystemItem class has those properties I was interested in displaying in the file browser -
CreationTime, and others - along with a
FileSystemType read-only property
that returns a friendly description based on the file's extension. (For example, for files with the extension
FileSystemType property returns the string "Microsoft Word document.")
Here is the code that creates the list of
FileSystemItem objects, loops through the
FileInfo arrays and adds them to the list of
FileSystemItem objects, and then binds that list to the GridView.
Note that adding information about a file or folder to the
fsItems list is done in one line of code, by calling
new FileSystemItemCS(file). As you may have surmised, the
FileSystemItem class offers two constructors, one that accepts a
object as input and another that accepts a
FileInfo object. Both constructors assign the passed-in object's property values to the new
FileSystemItem object's properties.
Drilling Into a Subfolder
Each subfolder is displayed in the GridView as a LinkButton whose
CommandArgumentproperty is assigned the name of the folder. When the LinkButton is clicked, a postback ensues and the GridView fires its
RowCommandevent. The User Control has a
RowCommandevent handler that updates the
CurrentFolderproperty and then calls the
PopulateGridmethod, to display the folders and files of the new folder in the grid.
When drilling down into a subfolder, the code is very straightforward - we can use the
Path.Combine method to combine the current folder path (
with the name of the folder the user clicked (
e.CommandArgument) and assign this value back to the
We have to do a bit more work when going up a directory (that is, when clicking the
.. folder, which is displayed when listing the contents of any folder other than
HomeFolder). Imagine that we are showing the contents of the folder
~/Content/Old/For Alice when the user asks to go up to the parent
folder. To accomplish this we need to hack off the last folder name (
For Alice), changing the
CurrentFolder property from
~/Content/Old/For Alice to
~/Content/Old. This can be done with some deft string manipulation - namely, splitting the string on all
directory delimiters and then piecing it back together but omitting the last part.
If you are not familiar with the string's
Join methods, understand
that they break up a string into an array of strings and piece an array of strings back together into a single string, respectively. In the code below, the
value of the
CurrentFolder folder is broken up into an array of strings using the backslash character as a delimiter. That is, a directory of
C:\MySites\Content\Old\For Alice would be split into an array with five items:
- For Alice
Joinmethod then says, "Put this array back into a string, but use only the first four elements in the array," resulting in a value of
C:\MySites\Content\Old, which is what is assigned back to the
The User Control presented in this article was designed to make it easy to add file browsing capabilities to an existing ASP.NET web page. As we discussed, the User Control can point to any folder on the web server's file system (either one in the web application's root or one outside it). There's also a User Control property to turn on and configure paging in the GridView (
All that being said, there are still a number of enhancements that could be added to this User Control. It would be nice to be able to enable sorting, for instance. Also, it would be ideal if instead of displaying a selected file the page developer using the file browser User Control could indicate that a postback should occur instead, at which point she could determine what file was selected and decide what to do with that request. Likewise, it would be nice to enable the page developer to turn on the ability to delete files.
You are welcome to make any enhancements. If you do, please feel free to share them with me! I hope to add some of these enhancements myself over time, at which point I'll update this article accordingly.