Manage Web Site Files With Ease

Create a powerful user control for your Web Sites using the DataGrid and System.IO classes.

asp:feature

LANGUAGES: VB .NET

TECHNOLOGIES: File Management | User Controls | DataGrid| System.IO

 

Manage Web Site Files With Ease

Create a powerful user control for your Web Sites using the DataGrid and System.IO classes.

 

By Bipin Joshi

 

All Web sites require a little data management, such as creating, deleting, moving, or renaming files and folders. For example, a Web site posting technical articles might need new files frequently. Later, someone might need to delete or move older articles.

 

If you have worked with free Web-hosting sites, you're probably aware of how they allow you to manage your files and folders. You might need to develop such a file manager for your ASP.NET Web sites. You can build the file manager as a user control so you can use it across multiple applications (for more on user controls, read User Controls by Doug Seven). Many people think you may use the ASP.NET DataGrid only with relational data. But I'll show you how to use the DataGrid to display your file-system details, and I'll show you how to make use of some infrequently used events of the DataGrid. I used VB .NET for this article, although you can use any .NET language.

 

Develop the File Manager

You'll use the DataGrid Web control as your file manager's base control. In addition to DataGrid, you'll use Label, TextBox, Button, and LinkButton Web server controls, as well as the File Field HTML server control for uploading files.

 

Start by creating a new ASP.NET Web project in Visual Studio .NET and name it SiteFileManager. Add a user control to the project by right-clicking on the project and selecting "Add web user control." Name the new user control SiteFileManagerControl.ascx.

 

You want the user control to look similar to the one shown in Figure 1, where the first two rows of the table display some general information; the third row contains label controls that display the current folder; and the fourth row contains buttons for various operations such as Delete, Cut, and Paste. That row also contains a textbox to specify the new folder name to create. On the fifth row, you can place a button for navigating up the folder tree. To create the table shown in Figure 1, you'll use HTML, the first part of which is shown in Figure 2.


Figure 1. Here's the basic user control. You'll use an HTML table to place the different controls.

 

 align="center" border="0"> ...

  

    

  

  

    

  

  

    

  

Figure 2. The header of the user control includes buttons for file management functions.

 

A DataGrid control follows the markup shown in Figure 2. The first two columns of the DataGrid are TemplateColumns. The first column contains a checkbox Web control you will use to indicate selection of a particular file. You cannot use the DataGrid's normal selection feature, SelectedIndex, because you want to allow for multiple selections. The second column contains a hyperlink to the file or folder. If the item is a file, clicking on the link should open the file in a new browser window. If the item is a folder, the link should navigate to that folder. The Last Modified and Size columns consist of BoundColumns. The last column consists of a ButtonColumn you'll use for renaming files. Figure 3 shows the markup for the DataGrid control.

 

  

Figure 3. The grid portion of the user control lists the files and folders inside the current folder.

 

The next row after the data grid contains controls for uploading files. Here, you use the InputFile HTML server control. If any errors are encountered during the application's execution, they will appear in the next row. Figure 4 shows the markup for this portion of the user control; the final two rows are for copyright information.

 

  

  

...

Figure 4. This portion of the user control contains the InputFile control, which users use to upload files to the Web site.

 

Create a FileManager Class

To make the code more maintainable, you create a class named FileManager. It will contain various properties and methods for manipulating the files and folders. Figure 5 contains a list of the FileManager class's properties and methods with brief descriptions of each.

 

      

       runat="server" Font-Bold="True"

       ForeColor="#FFFFC0">Current Folder :

      

      

       ForeColor="#FFFFC0" Width="291px" Height="19px">

      

    

     bgColor="navajowhite">

      

       Font-Bold="True">

        Delete    

      

       Font-Bold="True">

        Cut    

      

       Font-Bold="True">

        Paste   

      

       

      

       Font-Bold="True">Create Folder

        

      

       Font-Bold="True">Delete Current Folder

           

    

      

       Font-Bold="True" ForeColor="Maroon" Width="100%"

       BackColor="#FFFFC0" BorderWidth="1px"

       BorderStyle="None">[ Up ]

    

    

      Width="100%" BackColor="White" BorderWidth="1px"

     BorderStyle="None" AutoGenerateColumns="False"

     CellPadding="4" BorderColor="#CC9966">

      

      

      

       BackColor="#990000">

      

      

       ForeColor="#330099" BackColor="#FFFFCC">

      

      

       ForeColor="#663399" BackColor="#FFCC66">

      

      

      

      

        

          

            

            

          

        

        

          

            

             Text='<%# Container.DataItem("name") %>'>

            

          

          

            

             Text='<%# DataBinder.Eval(Container,

             "DataItem.name") %>'>

            

          

        

        

         ReadOnly="True" HeaderText="Last Modified">

        

        

          HeaderText="Size">

        

        

         UpdateText="Update"

         CancelText="Cancel" EditText="Rename">

        

      

    

  

    

     Font-Bold="True">

      Select File To Upload : 

      

      type="file" size="21" name="File1" runat="server">

     

    

     Font-Bold="True">

      Upload

  

    

     Font-Bold="True" Width="100%" Height="19px"

     BackColor="#FFFFC0" ForeColor="Red">

    

  

Property/ Method

Item

Data Type

Description

Property

ParentFolder

String

As the name suggests, the read-only ParentFolder property is used to get the full path of the current working folder's parent.

 

CurrentFolder

String

The CurrentFolder property is used to set or get the current working folder.

 

LastError

String

The read-only LastError property indicates any error that occurred during the last operation.

Method

FillFileList

n/a

Populates DataSet with a list of files from current folder.

 

FillFolderList

n/a

Populates DataSet with a list of sub-folders from current folder.

 

FillDataSet

DataSet

Calls above methods and returns resultant DataSet.

 

DeleteFile

n/a

Deletes a specified file.

 

MoveFile

n/a

Moves a specified file.

 

RenameFile

n/a

Renames a specified file.

 

CreateFolder

n/a

Creates a folder under current folder.

 

DeleteFolder

n/a

Deletes a folder.

Figure 5. These are the properties and methods in the FileManager class.

 

The FileManager class's FillDataSet method calls FillFileList and FillFolderList to fill the DataGrid control with files and folders, respectively:

 

Public Function FillDataSet() As DataSet

    Try

        FillFolderList()

        FillFileList()

    Catch

        mLastError = Err.Description

    End Try

    Return ds

End Function

 

The FillDataSet method calls the FillFileList and FillFolderList methods (see Figure 6).

 

Public Sub FillFileList()

  Dim filelist() As String = _

   Directory.GetFiles(CurrentFolder)

  For i = 0 To filelist.Length - 1

    Dim r As DataRow = files.NewRow

    Dim f As FileInfo

    f = New FileInfo(filelist(i))

    r("name") = f.Name

    r("modified") = f.LastWriteTime

    r("size") = f.Length

    files.Rows.Add(r)

  Next

End Sub

 

Public Sub FillFolderList()

  Dim folderlist() As String = _

   Directory.GetDirectories(CurrentFolder)

  For i = 0 To folderlist.Length - 1

    Dim r As DataRow = files.NewRow

    Dim f As DirectoryInfo

    f = New DirectoryInfo(folderlist(i))

    r("name") = f.Name

    r("modified") = f.LastWriteTime

    r("size") = " - "

    files.Rows.Add(r)

  Next

End Sub

Figure 6. These subroutines populate the DataSet with details of files and folders.

 

FillFileList gets a list of all the files from the current folder by calling the static GetFiles method of the Directory class from the System.IO namespace. The code loops through the returned array and adds rows to the file's DataTable, populating the Name, Modified, and Size columns. The FillFolderList method is identical to FillFileList, except it puts a hyphen in the Size column of the file's DataTable. To get details about the folder, FillFileList uses the DirectoryInfo class.

 

The SiteFileManagerControl

The user control's code-behind file (SiteFileManagerControl.ascx.vb) contains class variables, constants, and various event handlers. It starts out with these variables and constants:

Dim fm As FileManager

Dim ds As DataSet

Dim curpath As String

 

Const FILENAMECOLINDEX As Integer = 1

Const SIZECOLINDEX As Integer = 3

Const CHECKBOXCOLINDEX As Integer = 0

Const RENAMECOLINDEX As Integer = 4

 

The previous code makes use of constants to represent indexes of various columns. This allows you to change the position of any column with minimal effect to the code.

 

The Page_Load event of the user control is fired when the parent Web form loads it. In this case, this event creates an instance of the FileManager class by passing the physical path of the current folder; binds the DataGrid with the DataSet returned by the FillDataSet method of the FileManager class; and sets some labels, such as copyright information and a title. Figure 7 shows the code from this event handler.

 

Private Sub Page_Load(ByVal sender As System.Object, _

 ByVal e As System.EventArgs) Handles MyBase.Load

...

   If Request.QueryString("folder") = "" Then

     curpath = Request.PhysicalApplicationPath.TrimEnd("\")

   Else

     curpath = Request.QueryString("folder")

   End If

   fm = New FileManager( _

    Request.PhysicalApplicationPath.TrimEnd("\"), curpath)

   If Not Page.IsPostBack Then

     BindGrid()

   End If

End Sub

Figure 7. The FileManager instance is created by passing the base path and current path.

 

The code in Figure 7 is executed every time you trigger some action on the control. It first checks for the folder query string value. In the case where you are navigating the folder tree, this parameter is set to the current folder to be browsed. If the folder is blank, the code uses the Physical Application Path instead:

 

The BindGrid method binds the grid to the DataSet:

 

Public Sub BindGrid()

    ds = fm.FillDataSet()

    dgExplorer.DataSource = ds

    dgExplorer.DataMember = "files"

    dgExplorer.DataBind()

    lblCurrentFolder.Text = fm.CurrentFolder

    lblErrMsg.Text = fm.LastError

End Sub

 

This code sets the grid's DataSource and DataMember properties and calls the DataBind method. It also displays the current folder and error message (if any) in the appropriate labels.

 

Display Folders and Files in the DataGrid

All the code for displaying folders and files in the DataGrid takes place in the DataGrid's ItemDataBound event. The ItemDataBound event is raised after an item is bound to the DataGrid. This is a very important event handler for the control because it modifies the appearance of the grid for files and folders. For example, rows containing folders may not be selected via a check box. The event handler also sets hyperlinks for navigation. Figure 8 shows the code for this event handler.

 

Private Sub dgExplorer_ItemDataBound(ByVal sender As _

 Object, ByVal e As System.Web.UI.WebControls. _

 DataGridItemEventArgs) Handles dgExplorer.ItemDataBound

 

   Dim l As HyperLink

   If e.Item.ItemType = ListItemType.Item Or _

    e.Item.ItemType = ListItemType.AlternatingItem Then

     If e.Item.Cells(sizecolindex).Text = " - " Then

       l = CType(e.Item.Cells(filenamecolindex). _

        Controls(1), HyperLink)

       l.NavigateUrl = Request.Path & "?folder=" & _

        curpath & "\" & l.Text

       e.Item.Cells(checkboxcolindex).Text = ""

       e.Item.Cells(renamecolindex).Text = ""

     Else

       l = CType(e.Item.Cells(filenamecolindex). _

        Controls(1), HyperLink)

       If Request.QueryString("folder") = "" Or _

        Request.QueryString("folder") = fm.BaseFolder Then

          l.NavigateUrl = Request.ApplicationPath & "/" & _

           l.Text

       Else

          Dim path1 As String

          Dim path2 As String

          Dim result As String

          path1 = Request.PhysicalApplicationPath. _

           TrimEnd("\")

          path2 = Request.QueryString("folder")

          result = path2.Substring(path1.Length + 1)

          result = Request.ApplicationPath & "/" & _

           result & "/" & l.Text

          l.NavigateUrl = result

       End If

       l.Target = "_blank"

     End If

   End If

   If Request.QueryString("folder") <> "" Then

     If e.Item.ItemType = ListItemType.Header Then

       If fm.ParentFolder <> "" Then

          lnkUp.NavigateUrl = Request.Path & _

           "?folder=" & fm.ParentFolder

       Else

          lnkUp.NavigateUrl = ""

       End If

     End If

   End If

End Sub

Figure 8. The DataGrid's ItemDataBound event handler sets and clears CheckBoxes from folder rows, and it sets navigation links and "Up" link button properties.

 

The code first loops through all the items of the grid and checks whether an item is of the Item or AlternatingItem type. You can determine whether an item is a file or folder by examining the Size column. If the Size column contains a hyphen, it is a folder and you need to change the item's NavigateUrl property to point to the underlying folder. You also need to remove the check boxes for folder items so the user cannot select them while performing operations such as delete. If the item is a file, you change the NavigateUrl to point to the file's URL. If the user clicks on this link, the file will be opened in a blank window as set by the hyperlink's Target property. The Up hyperlink is set to point to the parent folder.

 

Move, Delete, and Rename Files

The file manager allows you to select multiple files to move to another location. The code to accomplish this feat lies in the click event of the cmdCut button (see Figure 9).

 

Private Sub cmdCut_Click(ByVal sender As System.Object, _

 ByVal e As System.EventArgs) Handles cmdCut.Click

    Dim curfolder As String = fm.CurrentFolder

    Dim item As DataGridItem

    Dim filestomove As String

    Dim l As HyperLink

 

    For Each item In dgExplorer.Items

        If item.Cells(0).Controls.Count > 0 Then

            Dim c As CheckBox

            c = item.Cells(0).Controls(1)

            If c.Checked Then

                Dim filename As String

                l = item.Cells(filenamecolindex). _

                 FindControl("hyperlink1")

                filestomove = filestomove & _

                 fm.CurrentFolder & "\" & l.Text & ";"

            End If

        End If

    Next

    Session.Add("filestomove", filestomove)

     BindGrid()

End Sub

Figure 9. Selected files and their paths are maintained in the Session variable.

 

The code in Figure 9 loops through all the items of the DataGrid and, for each row, determines whether the check box is selected. If the check box is checked, it retrieves the path of the file and stores it in a string variable, separating multiple files with commas and storing the string in a Session variable. The user is then able to navigate to another folder and perform a Paste operation. This operation happens on the cmdPaste button's click event (see Figure 10).

 

Private Sub cmdPaste_Click(ByVal sender As System.Object, _

 ByVal e As System.EventArgs) Handles cmdPaste.Click

    If Not Session.Item("filestomove") Is Nothing Then

        Dim filenames() As String = _

         Session.Item("filestomove").ToString().Split(";")

        Dim i As Integer

        For i = 0 To filenames.Length - 2

            fm.MoveFile(filenames(i), fm.CurrentFolder & _

             "\" & Path.GetFileName(filenames(i)))

         Next

    End If

    Session.Remove("filestomove")

    BindGrid()

End Sub

Figure 10. When a user clicks on the Paste button, filenames are retrieved from a session variable and the files are moved to the current folder.

 

The code in Figure 10 splits the string into an array and calls the MoveFile method of the FileManager class for each file.

 

The code for deleting files is similar to the code for moving files, following the same steps of iterating the grid for selected files. Instead of storing the resulting selection in a Session variable, however, the delete code calls the FileManager's DeleteFile (see Figure 11).

 

Private Sub cmdDelete_Click(ByVal sender _

 As System.Object, ByVal e _

 As System.EventArgs) _

 Handles cmdDelete.Click

    Dim curfolder As String = fm.CurrentFolder

    Dim item As DataGridItem

    Dim l As HyperLink

 

    For Each item In dgExplorer.Items

        If item.Cells(0).Controls.Count > 0 Then

            Dim c As CheckBox

            c = item.Cells(0).Controls(1)

            If c.Checked Then

                Dim filename As String

                l = item.Cells(filenamecolindex). _

                 FindControl("hyperlink1")

                fm.DeleteFile(Path.GetFileName _

                  (l.NavigateUrl))

            End If

         End If

    Next

    BindGrid()

End Sub

Figure 11. Files marked for deletion are found by looping through DataGrid items, then the selected files are deleted.

 

To rename files, you will use the DataGrid control's in-place editing features. The key code lies in the event handlers for the grid's EditCommand, UpdateCommand, and CancelCommand events. Figure 12 shows these event handlers.

 

Private Sub dgExplorer_EditCommand(ByVal source _

 As Object, _

 ByVal e As System.Web.UI.WebControls. _

 DataGridCommandEventArgs) Handles dgExplorer.EditCommand

    Dim filename As String

    Dim l As HyperLink

    l = e.Item.Cells(filenamecolindex). _

     FindControl("hyperlink1")

    Session.Add("filetorename", l.Text)

    dgExplorer.EditItemIndex = e.Item.ItemIndex

    BindGrid()

End Sub

 

Private Sub dgExplorer_UpdateCommand(ByVal source As _

 Object, ByVal e As System.Web.UI.WebControls. _

 DataGridCommandEventArgs) Handles dgExplorer.UpdateCommand

    Dim t As TextBox

    t = CType(e.Item.Cells(filenamecolindex).Controls(1), _

     TextBox)

    fm.RenameFile(Session("filetorename").ToString, t.Text)

    dgExplorer.EditItemIndex = -1

    BindGrid()

End Sub

 

Private Sub dgExplorer_CancelCommand(ByVal source As _

 Object, ByVal e As System.Web.UI.WebControls. _

 DataGridCommandEventArgs) Handles dgExplorer.CancelCommand

    dgExplorer.EditItemIndex = -1

    BindGrid()

End Sub

Figure 12. The user can edit the filename by clicking on the Rename link button. The user can then save changes or cancel the operation.

 

When you click on the Rename button, the EditCommand event fires. The code prompts the user to enter a new filename in a textbox and stores the old filename in a session variable. Once the user enters a new filename and clicks on the Update button, the UpdateCommand event fires. The code in this event handler calls the RenameFile method of the FileManager class, passing it the old and new names. The CancelCommand event fires if the user chooses not to rename the file by clicking on the Cancel button.

 

Create and Delete Folders

To create a new folder, a user enters the folder name into the provided textbox and clicks on the CreateFolder button:

 

Private Sub cmdCreateFolder_Click(ByVal sender As _

 System.Object, ByVal e As System.EventArgs) _

 Handles cmdCreateFolder.Click

   fm.CreateFolder(txtFolderName.Text)

   BindGrid()

End Sub

 

The link button's click event simply calls the FileManager class's CreateFolder method.

 

When the user clicks on the Delete Folder button, the current working folder is deleted and the user is taken back to the root folder:

 

Private Sub cmdDelFolder_Click(ByVal sender As _

 System.Object, ByVal e As System.EventArgs) _

 Handles cmdDelFolder.Click

   fm.DeleteFolder(fm.CurrentFolder)

   Response.Redirect(Request.Path)

End Sub

 

ASP.NET offers a far easier way to upload files compared to ASP Classic. In order to upload a file to the current working folder, the user selects a file using the File Field control and then clicks on the Upload button. Amazingly, uploading the file is a matter of a single line of code:

 

Private Sub cmdUpload_Click(ByVal sender As _

 System.Object, ByVal e As System.EventArgs) _

 Handles cmdUpload.Click

    File1.PostedFile.SaveAs(fm.CurrentFolder & "\" & _

     Path.GetFileName(File1.PostedFile.FileName))

    BindGrid()

End Sub

 

The code saves the file to the current working folder with the same name as the file on the user's machine. The PostedFile class provides the SaveAs method, which actually stores the file.

 

To test the file manager user control, you need to add a Web form to your project. First, register the user control on the Web form using the @Register directive:

 

<%@ Register TagPrefix="uc1"

  TagName="SiteFileManagerControl"

  Src="SiteFileManagerControl.ascx" %>

 

Note that uc1 is the tag prefix generated automatically by VS .NET, and you can change it to something more user-friendly. The src attribute points to the ascx file for the user control. Once you register the user control, you can create instances of the control with code like this:

 

 encType="multipart/form-data">

   

    runat="server">

   

 

If you build and browse the Web form, you should get the file manager ready to use.

 

Nothing is perfect, and your file manager is no exception. The file manager control, as you have developed it, performs most of the tasks as expected. Still, it lacks some features that would be nice to have, such as marking folders to cut with a different color; confirming that a file or folder has been deleted; displaying an error message in case folder deletion fails; adding a security feature so only authorized users can access it; and converting the user control into a custom Web control. Still, ASP.NET's DataGrid control is flexible, and you can use it in many innovative ways. Thanks to ASP.NET, tasks such as manipulating and uploading files and folders are much simpler.

 

The files referenced in this article are available for download.

 

Bipin Joshi is a Microsoft MVP, software developer, and author. He has a strong background in VB, COM, and ASP, and now he works with .NET technologies. He is a co-author of Professional ADO.NET and Professional XML for .NET Developers (Wrox). Visit his Web site at for more information on .NET technologies at http://www.DotNetBips.com.

 

What Should the File Manager be Able to Do?

Before you start coding, here's a list of the tasks the file manager should be able to perform.

 

1) Display a list of all the files in the current working folder, including the file size and the last modification date.

2) Allow you to navigate the folder tree easily.

3) Allow you to create new text documents.

4) Allow you to create new folders.

5) Allow you to delete files.

6) Allow you to delete folders.

7) Allow you to move files.

8) Allow you to rename files.

9) Allow you to upload files one at a time.

10) Display the appropriate error message in case it fails to execute any task.

 

Tell us what you think! Please send any comments about this article to [email protected]. Please include the article title and author.

 

 

 

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish