Displaying Files and Folders in a GridView
By Scott Mitchell
Introduction
The .NET Framework provides a variety of classes in the
System.IO
namespace 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 D:\Reports
.
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 For Jisun
, Images
, and Old
,
and a number of files, including 010401-1.txt
, f1040ez.pdf
, and 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 ~/Content
folder then clicking the f1040ez.pdf
file in the grid to the right would send the user to www.yoursite.com/Content/f1040ez.pdf
, which
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
and FileGridCS.ascx.cs
files; if you use Visual
Basic, copy the FileGridVB.ascx
and FileGridVB.ascx.vb
files.) Also copy the ~/Images/folder.png
image from the sample application to
the ~/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 App_Code
.
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:
- A
@Register
directive 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" />
HomeFolder
property. 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:
D:\Public\Report Files
.
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
its 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:
<uc1:FileGridVB ID="FileGridVB1" runat="server" HomeFolder="~/Content" PageSize="10" />
|
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
DirectoryInfo
class to retrieve
the list of files and folders in the folder of interest. To use the DirectoryInfo
class 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 CurrentFolder
property is equal to its HomeFolder
property, but the CurrentFolder
property 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.)
private void PopulateGrid()
|
Once we have a DirectoryInfo object, we can use the GetDirectories
and
GetFiles
methods to get information about the directory's subfolders and files.
The GetDirectories
method returns an array of DirectoryInfo
objects; the GetFiles
method returns an array of
FileInfo
objects. The DirectoryInfo
and FileInfo
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.
var folders = currentDirInfo.GetDirectories();
|
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.
This FileSystemItem
class has those properties I was interested in displaying in the file browser -
Name
, FullName
, Size
, 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 .doc
and .docx
the
FileSystemType
property returns the string "Microsoft Word document.")
Here is the code that creates the list of FileSystemItem
objects, loops through the DirectoryInfo
and FileInfo
arrays and adds them to the list of
FileSystemItem
objects, and then binds that list to the GridView.
var fsItems = new List<FileSystemItemCS>();
|
Note that adding information about a file or folder to the fsItems
list is done in one line of code, by calling new FileSystemItemCS(folder)
or new FileSystemItemCS(file)
. As you may have surmised, the FileSystemItem
class offers two constructors, one that accepts a DirectoryInfo
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
CommandArgument
property is assigned the name of the folder. When the LinkButton is clicked,
a postback ensues and the GridView fires its RowCommand
event. The User Control has a RowCommand
event handler that updates the CurrentFolder
property and then calls the PopulateGrid
method, 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 (CurrentFolder
)
with the name of the folder the user clicked (e.CommandArgument
) and assign this value back to the CurrentFolder
property.
protected void gvFiles_RowCommand(object sender, GridViewCommandEventArgs e)
|
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
the 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 Split
and 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:
- C:
- MySites
- Content
- Old
- For Alice
Join
method 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 CurrentFolder
property.
var currentFullPath = this.CurrentFolder;
|
Looking Forward...
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 (
PageSize
).
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.
Happy Programming!
Attachments: