Search   Articles   Dev Forums   Personalize   Favorites   Member Login   ASP.Net Hosting
DevASP.NET for ASP.NET, VB.NET, XML and C# (C-Sharp) Developers Sunday, November 23, 2008

Dev Articles
Search Directory
ASP.NET
VB.Net
C-Sharp
SQL Server
 

Creating Directories


So far we've seen the features of a typical file explorer (with the addition of a file uploader), but since we're building a file manager, we should also add functionality that will allow us to change the content and the structure of the site. We're going to implement many features in this category of commands; the first we'll see is the command to create a new directory.

 

Our designers want to create a toolbar with a link that, when pressed, pops up a dialog and asks for the name of the directory to create. As you might guess, this is not done by ASP.NET code, but rather by client-side JavaScript code, through the prompt function. If the user presses Cancel, nothing happens, but if the user types the name of the folder they want to create and presses OK, we have to pass this parameter back to the ASP.NET page that will actually create the directory and refresh the table.

 

The first thought might be to redirect to the current page and add the folder to create as a parameter in the URL. But ASP.NET is great because of its event procedures that handle the postbacks generated by specific controls, so why not use this cool feature? To do so, we need to have a clear understanding about the way the form is posted back when a button or a hyperlink control is pressed.


To demonstrate this we created a test page, which is not part of the final application. In it we placed a HyperLink control, as follows:

 

<asp:LinkButton ID="test" runat="server" Text="Demo" OnClick="Test_Click" />

 

Next, we wrote an empty Test_Click procedure in the code-behind, compiled and then ran the page. This is the HTML code produced:

 

...

<a id="Test" href="javascript:__doPostBack('Test','')">Demo</a>

...

<input type="hidden" name="__EVENTTARGET" value="" />

<input type="hidden" name="__EVENTARGUMENT" value="" />

<script language="javascript">

<!--

  function __doPostBack(eventTarget, eventArgument) {

    var theform = document.BrowseFiles;

    theform.__EVENTTARGET.value = eventTarget;

    theform.__EVENTARGUMENT.value = eventArgument;

    theform.submit();

  }

// -->

</script>

...

 

As you can see, there is nothing magic here. When the link is pressed, instead of redirecting to another page, the __doPostBack JavaScript function is called. The first parameter that the function requires is the name of the control that is going to post back the form and generate the event on the server. The second parameter may contain additional information for the event, but it is empty in this case, and in fact the Click event has no additional information in the standard e parameter.

 

What the __doPostBack actually does is to set two hidden input controls, with the values passed in the input. Then it submits the form. On the server, the ASP.NET engine extracts the values of those two hidden controls, and calls the server event handler. Again, nothing magic… but very cool!

 

In conclusion, all the server controls do to post back the form is to call the __doPostBack function, but we can also do this by writing the HTML code by hand.

 

Back to our original problem: we can create a link that, when clicked, calls a JavaScript function. This function pops up the prompt dialog asking for a name. If the user presses OK, the function can save the specified folder name in a hidden field, and call the __doPostBack function to post back the form. All done then? Almost. Remember that the first parameter of the function is the name of the server control whose Click event (in this case, it might be a different event for other controls) will be raised. This control must actually exist on the page, but we can avoid setting its Text property and so make it invisible, and we add it just to use its associated Click event.


Let's look at the code in the ASP.NET page, BrowseFiles.aspx, to better explain how to do this. The code contains the JavaScript that asks for the new directory, the LinkButton, and the hidden control declaration:

 

...

<html>

  <head>

    <title>FileManager: Browse Files</title>

    <link rel="stylesheet" href="/ThePhile/Styles/ThePhile.css"

        TYPE="text/css" />

    <meta name="CODE_LANGUAGE" Content="C#">

    <script language="javascript">

      function CreateDir()

      {

        dirName = prompt('Type the name of the directory you want to

            create:','');

 

        if ((dirName) && (dirName!=""))

        {

          document.forms['BrowseFiles'].elements['funcParam'].value =

                                                                  dirName;

          __doPostBack('CreateDir', '');

        }

      }

    </script>

  </head>

  <body>

    <form id="BrowseFiles" method="post" runat="server"

        enctype="multipart/form-data">

      <FileManager:Header ID="Title" runat="server" />

      <input type="hidden" id="funcParam" runat="server">

      <table class="MenuTable" border="0" width="100%">

        <tr>

          <td>

            <a href="javascript:CreateDir();">

              <img border="0" src="./Images/NewFolder.gif"

                  Alt="Create a new directory" height="28" width="28" />

            </a>

            <asp:LinkButton ID="CreateDir" runat="server"

                OnClick="CreateDir_Click" />

          </td>

        </tr>

      </table>

      <br>

      <asp:Table runat="server" CssClass="Grid_Header_Thin"

          Width="100%" ID="Table1">

        <asp:TableRow>

          <asp:TableCell Width="36">

            <asp:Image runat="server" Height="32"

                Width="32" ImageUrl="./Images/OpenFolder.gif" />

          </asp:TableCell>

         

The rest is unchanged...         


 

You might be wondering why we completely avoided setting the Text property instead of simply setting its Visible property to False. The reason is that we need at least one control recognized by ASP.NET as a control that generates postbacks through a call to __doPostBack. Otherwise ASP.NET detects that there is no need for the __doPostBack function and does not include it in the generated HTML code for the client, which would cause an error when our CreateDir function calls it. A control with the Visible="False" attribute is not created in the HTML, and so neither is __doPostBack. Therefore, we need to declare the control, leaving out the Visible property, so that the JavaScript function is created. Once we have this control, the other similar LinkButton controls we'll use later can be made invisible by the Visible="False" attribute.

In the code-behind we first declare the hidden control used to store the new folder name:

 

protected System.Web.UI.HtmlControls.HtmlInputHidden funcParam;

 

Then we have the Click event handler for the CreateDir ButtonLink:

 

protected void CreateDir_Click(object sender, EventArgs e)

{

 

  // build the complete path (current path + new dir name)

  string path = folderPath;

  if (path.EndsWith("/"))

    path += funcParam.Value;

  else

    path += "/" + funcParam.Value;

   

  try

  {

 

    // create the directory

    Directory.CreateDirectory(Server.MapPath(path));

 

    // refresh the page

    Response.Redirect("BrowseFiles.aspx?Folder=" + folderPath);

  }

  catch (Exception exc)

  {

    StatusMessage.Text = exc.Message;

    StatusMessage.Visible = true;

  }

}

 

As usual, the possible exception is handled and an error message is shown. If the new directory is created successfully, the page is refreshed and the table re-filled with the updated content.


In this example we've taken advantage of both the client-side script and the ASP.NET event handling mechanism. The following screenshot shows the updated file manager and its dialog to enter the new directory name:

 

Creating Text Files

If we allow the administrator to create directories, we must also provide the opportunity to create text files (not empty text files of course, but files with some content). The approach is exactly the same as we used to implement the last command: manually calling the __doPostBack function from a JavaScript routine executed by an image link. The new code in the ASPX page is as follows:

 

...

<head>

  <title>FileManager: Browse Files</title>

  <link rel="stylesheet" href="/ThePhile/Styles/ThePhile.css"

      TYPE="text/css" />

  <meta name="CODE_LANGUAGE" Content="C#">

  <script language="javascript">

 

    function CreateDir()

    {


    ... unchanged from above ...           

    }

       

    function CreateFile()

    {

      fileName = prompt('Type the name of the file you want to create:','');

 

      if ((fileName) && (fileName!=""))

      {

        document.forms['BrowseFiles'].elements[

          'funcParam'].value = fileName;

        __doPostBack('CreateFile', '');

      }

    }

  </script>

</head>

<body>

  <form id="BrowseFiles" method="post" runat="server"

      enctype="multipart/form-data">

    <FileManager:Header ID="Title" runat="server" />

    <input type="hidden" id="funcParam" runat="server">

      <table class="MenuTable" border="0" width="100%">

        <tr>

          <td>

            <a href="javascript:CreateDir();">

              <img border="0" src="./Images/NewFolder.gif"

                Alt="Create a new directory" height="28" width="28" />

            </a>

            <asp:LinkButton ID="CreateDir" runat="server"

                OnClick="CreateDir_Click" />

            <a href="javascript:CreateFile();">

              <img border="0" src="./Images/NewFile.gif"

                  Alt="Create a new text file" height="28" width="28">

            </a>

            <asp:LinkButton ID="CreateFile" runat="server"

                OnClick="CreateFile_Click" Visible="False"/>

          </td>

        </tr>

      </table>

      ...

 

And here's the addition for the code-behind:

 

protected void CreateFile_Click(object sender, EventArgs e)

{

  string path = folderPath;

  if (path.EndsWith("/"))

    path += funcParam.Value;

  else

    path += "/" + funcParam.Value;

   

  // if the file already exists, do not go to the text editor

  if (File.Exists(Server.MapPath(path)))


  {

    StatusMessage.Text = "The file you specified already exists.";

    StatusMessage.Visible = true;

  }

  else

    // redirect to the editor page

    Response.Redirect("EditFile.aspx?File=" + path + "&CreateFile=true");

}

 

The code above first of all checks if the specified file already exists (the whole path is retrieved by combining the current path and the name specified). If so, it just shows an error message – later in the chapter we'll add the possibility to edit an existing file. Otherwise it redirects to EditFile.aspx with the full virtual path of the file to create as a parameter, and another parameter, CreateFile, set to true. We're going to write this new page in the next section.

Building the Text File Editor

We want to build a very simple text editor that allows us to create a new file and also to edit an existing file. The editor will just have a multi-line textbox, a textbox for the destination path, a button to create or update the file, and another button to discard the changes and go back to the file manager.

 

In VS.NET create a new web form, named EditFile.aspx, and edit its content as follows:

 

<%@ Page language="c#" Codebehind="EditFile.aspx.cs" AutoEventWireup="false"

    Inherits="Wrox.WebModules.FileManager.Web.EditFile" %>

<%@ Register TagPrefix="FileManager" TagName="Header" src="Header.ascx" %>

<%@ Register TagPrefix="FileManager" TagName="Footer" src="Footer.ascx" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >

<html>

  <head>

    <title>FileManager: text editor</title>

    <link rel="stylesheet" href="/ThePhile/Styles/ThePhile.css"

        TYPE="text/css" />

    <meta name="CODE_LANGUAGE" Content="C#">

  </head>

  <body>

    <FileManager:Header ID="Title" runat="server" />

    <form ID="EditFile" method="post" runat="server">

      <asp:Table runat="server" CssClass="Grid_General" Width="100%">

        <asp:TableRow CssClass="Grid_Header">

          <asp:TableCell HorizontalAlign="Center" Text="EDIT TEXT FILE" />

        </asp:TableRow>

        <asp:TableRow>

          <asp:TableCell HorizontalAlign="Center">

            <asp:TextBox runat="server" Width="99%" Rows="20"

              TextMode="MultiLine" ID="FileContent" CssClass="TextBox" />

          </asp:TableCell>

        </asp:TableRow>

        <asp:TableRow>

          <asp:TableCell HorizontalAlign="Right" Text="Save As:">

            <asp:TextBox runat="server" Width="350px"

                ID="SaveAsPath" CssClass="TextBox" />


            <asp:Button runat="server" Text="Save" ID="Save"

                CssClass="Button" Width="80px" OnClick="Save_Click"

                />&nbsp;

            <asp:Button runat="server" Text="Back to FileManager" ID="Back"

                CssClass="Button" Width="150px"

                OnClick="Back_Click" CausesValidation="False" />

          </asp:TableCell>

        </asp:TableRow>

        <asp:TableRow>

          <asp:TableCell HorizontalAlign="Right">

            <asp:RequiredFieldValidator ID="ValidateSaveAsPath"

                runat="server" ControlToValidate="SaveAsPath"

                Display="dynamic">* The Save As path is required

            </asp:RequiredFieldValidator>

            <asp:Label runat="server" ID="StatusMessage"

                CssClass="StatusMessage" Visible="False" Width="100%" />

          </asp:TableCell>

        </asp:TableRow>

      </asp:Table>

      <br>

    </form>

    <FileManager:Footer ID="Footer" runat="server" />

  </body>

</html>

 

We added a RequiredFieldValidator control that ensures that the SaveAsPath field is not empty when the form is submitted. Also, when we press the Back to FileManager button the form should not be validated, and that's why we set its CausesValidation property to False.

The Code-behind for EditFile.aspx

The code-behind for this page is not long, and is quite simple, but we'll show it piece by piece, starting from the beginning and including the Page_Load procedure:

 

using System;

using System.Collections;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Web;

using System.Web.SessionState;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.HtmlControls;

using System.IO;

 

namespace Wrox.WebModules.FileManager.Web

{

  public class EditFile : System.Web.UI.Page

  {

    protected System.Web.UI.WebControls.Label StatusMessage;

    protected System.Web.UI.WebControls.TextBox SaveAsPath;

    protected System.Web.UI.WebControls.TextBox FileContent;


    protected System.Web.UI.WebControls.Button Save;

    protected System.Web.UI.WebControls.Button Back;

 

    private void Page_Load(object sender, EventArgs e)

    {

      if (!IsPostBack)

      {

        string filePath = Request.Params["File"];

        if (filePath != null)

        {

          if (Request.Params["CreateFile"] == null ||

            Request.Params["CreateFile"]=="false")

          {

            // load the content of the specified text file

            try

            {

              StreamReader sr = new StreamReader (File.Open(

                               Server.MapPath(filePath), FileMode.Open) );

              FileContent.Text = sr.ReadToEnd();

              sr.Close();

            }

            catch (Exception exc)

            {

              StatusMessage.Text = exc.Message;

              StatusMessage.Visible = true;

            }

          }

          // set the Save As textbox with the path

          // specified in the QueryString

          SaveAsPath.Text = filePath;

        }

      }

 

The Page_Load procedure extracts the path of the file to create or edit from the QueryString. Then it checks if there is a CreateFile parameter set to false, or not present at all. In both these cases it means that the file is already present and the user does not want to create it, but rather to edit it. So the procedure opens the file, reads its content, and shows it in a large textbox (this code is protected within a trycatch block as usual).

 

The next block of code is the procedure called when the Back to FileManager button is pressed. Basically, it extracts the parent folder of the file passed in the QueryString, and redirects to BrowseFiles.aspx, pointing to the folder to browse:

 

    protected void Back_Click(object sender, EventArgs e)

    {

      // redirect to the referrer URL or to the BrowseFiles.aspx page

      // if the referrer is null

      string filePath = Request.Params["File"];

      if (filePath != null && filePath != "/")

      {

        int lastSlashIndex = filePath.LastIndexOf("/");

        string folderPath = filePath.Substring(0, lastSlashIndex+1);

        Response.Redirect("BrowseFiles.aspx?Folder=" + folderPath);

      }

      else

        Response.Redirect("BrowseFiles.aspx");

    }


Finally, the last procedure is executed when the user presses the Save button. The file is created or updated with the new content:

 

    protected void Save_Click(object sender, EventArgs e)

    {

      // save the text to the specified file

      // (the file is created from scratch even if it already exists)

      try

      {

        string filePath = SaveAsPath.Text;

        if (!filePath.StartsWith("/")) filePath = "/" + filePath;

        StreamWriter sw = File.CreateText(Server.MapPath(filePath));

        sw.Write(FileContent.Text);

        sw.Close();

        StatusMessage.Text = "File successfully saved";

      }

      catch (Exception exc)

      {

        StatusMessage.Text = exc.Message;;

      }

      StatusMessage.Visible = true;

    }

 

    // ... other code created by default by VS.NET for the Designer support

  }

}

 

Note that the file is created from scratch in all cases. In other words, if the file already exists it is overwritten by a new file.

 

At this point we can recompile the assembly with the new page and switch to the browser. Click the Create a new text file icon on the toolbar, specify any file name you want (for example MyTestFile.txt) and confirm. This displays a page like this:

 


 

Editing Files

So, we've developed a page that allows the user to create and edit a new text file. We will now go back to the BrowseFiles.aspx page and add a new column with a link to the file editor for all the
text files.

 

Here's the new column for the FoldersAndFilesTable table (this is the last time you need to change it, I promise):

 

<asp:Table ID="FoldersAndFiles" runat="server"

    CssClass="Grid_General" Width="100%">

  <asp:TableRow CssClass="Grid_Header">

    <asp:TableCell Width="36px" />

    <asp:TableCell Text="Index" />

    <asp:TableCell Width="25px" />

    <asp:TableCell Width="45px" />

    <asp:TableCell Text="Attribs" Width="50px" />

    <asp:TableCell Text="Size" Width="80px" HorizontalAlign="Right" />

    <asp:TableCell Text="Created" Width="140px" />

    <asp:TableCell Text="Last Modified" Width="140px" />

  </asp:TableRow>

</asp:Table>

 

Then, in the FillFoldersAndFilesTable routine in the code-behind file, add a new empty column (cellOperations) for the first row, which links to the parent folder, and for all directory rows. (This is not shown here, look at the code earlier in the chapter to see how to add columns, for example in the Displaying the Item Attributes section). We're going to add a link for any text files that are not read-only or system files. We won't add a link for the other files (we can't edit a GIF with a text editor).

 

The easiest way to decide whether a file is a text file is by looking at its extension. If the extension is .txt, .log, .bat, .cs, .config, .aspx, or some other well-known text file extension, then we should be reasonably sure that the file is a text file. We define an array - private for the entire class - of known extensions, as we did for associating the extensions with an icon:

 

private string[] textExtensions = new string[]{".asa", ".asax",

  ".ascx", ".asmx", ".asp", ".aspx", ".bat", ".config", ".cs",

  ".css", ".disco", ".htm", ".html", ".inc", ".ini", ".log",

  ".sys", ".txt", ".vb", ".vbs", ".vsdisco", ".xls", ".xml"};

 

We could handle the list of text files in other ways, which would integrate with the system of assigning icons to extensions. We would create an XML file that lists the extensions for which we have an icon, where the tag has the name of the extension, and can have a "text" attribute that tells whether the files with that extension are editable through our text editor. Here is an example XML file:

 

<extensions>

    <.aspx text="true"><aspx.gif></.aspx>

    <.bmp><bmp.gif></.bmp>

    <.gif><gif.gif></.gif>

    <.html text="true"><html.gif></.html>

    <.zip><zip.gif></.zip>

     …

</extensions>


This solution would provide the flexibility to add, edit and delete extensions without the need to recompile the assembly. However, working with an XML file is much slower than working with an array in a local private variable, and requires more code and resources. Considering that once you've set up a complete list of extensions you want to support you won't need to update it frequently, employing the XML solution is probably not worth the effort – but it's an option if you want the maximum flexibility and ease of use for the site administrator.

 

Now, code block that adds the child files to the table, we declare the new cell, and check if the current file's extension is listed in the array and if the file is write-enabled. If both conditions are satisfied the new icon link is added to the column:

 

...

TableCell cellOperations;

...

 

foreach (FileInfo childFile in childFiles)

{

  // create the required cells and controls

  ...

  cellOperations = new TableCell();

  int extIndex;

 

  // set the other cells and controls

  ...

   

  // if this file is a text file and is write-enabled, add an image

  // link that points to EditFile.aspx with its path as the parameter

  extIndex = Array.IndexOf(textExtensions, childFile.Extension.ToLower());

  if (extIndex > -1 &&

    (childFile.Attributes & FileAttributes.ReadOnly) !=

        FileAttributes.ReadOnly &&

    (childFile.Attributes & FileAttributes.System) !=

        FileAttributes.System)

  {

    // create the link and set its properties

    HyperLink linkEditFile = new HyperLink();

    linkEditFile.Text = "<img src=\"./Images/Write.gif\" height=\"16\ +

        " width=\"16\" border=\"0\" alt=\"Edit this file\">";

    linkEditFile.NavigateUrl = "EditFile.aspx?File=" + location;

    cellOperations.Controls.Add(linkEditFile);

  }

 

  // add the cells to the new row

  rowItem.Cells.Add(cellItemIcon);

  rowItem.Cells.Add(cellItemLink);

  rowItem.Cells.Add(cellDownload);

  rowItem.Cells.Add(cellOperations);

  ...

}


Renaming Files and Directories

The next command to implement is one for renaming files or directories. We're going to add a new button to each row in the table, except the first one, if it is the one that points to the parent folder. When pressed, the button will pop up a prompt dialog. If the new name is confirmed then an event will be raised on the server and handled by the proper procedure.

 

We've already seen how to use JavaScript for postbacks when we showed how to create a new directory or file. What's new here is that we're going to have an unknown number of buttons (one for each row, used to rename the item represented by the row where it is located) that will all raise the same event on the server. This does not make any difference to the actual implementation – we don't need to identify which row was clicked, just the original path name.

 

The other difference is that we need to submit two pieces of information – the original path name, and the new name. Although we could pack both of these parameters into a single control, adding a new hidden control produces no overhead and makes it simpler to extract the information.

 

In the ASPX page we just create the new hidden control, the JavaScript function that asks for the new name, and the invisible LinkButton control. The links that call this function are dynamically created in the code-behind for each file and directory.

 

Here's the additional code for BrowseFiles.aspx:

 

...

<head>

  <title>FileManager: Browse Files</title>

  <link rel="stylesheet" href="/ThePhile/Styles/ThePhile.css"

      TYPE="text/css" />

  <meta name="CODE_LANGUAGE" Content="C#">

  <script language="javascript">

 

    function CreateDir()

    {

      ...

    }

       

    function CreateFile()

    {

      ...

    }

       

    function Rename(path)

    {

      newName = prompt('Type the new name for this file/folder:','');

 

      if ((newName) && (newName!=""))

      {

        document.forms['BrowseFiles'].elements['funcParam'].value = path;

        document.forms['BrowseFiles'].elements['funcExtraParam'].value =

            newName;

        __doPostBack('Rename', '');

      }


    }

  </script>

</head>

<body>

  <form id="BrowseFiles" method="post" runat="server"

      enctype="multipart/form-data">

    <FileManager:Header ID="Title" runat="server" />

    <input type="hidden" id="funcParam" runat="server">

    <input type="hidden" id="funcExtraParam" runat="server">

    <table class="MenuTable" border="0" width="100%">

      <tr>

        <td>

          ... other LinkButtons and links for the Toolbar commands   

          <asp:LinkButton ID="Rename" runat="server"

              OnClick="Rename_Click" Visible="False" />

        </td>

      </tr>

    </table>

    ...

 

We don't need to add a new column, as we're going to add the new link to the column with the Edit File icon. However, in the code-behind we need to create and add this column for the directories too, because the last time we modified it we just added an empty column.

 

Here are the additions for the code-behind, starting with FillFoldersAndFilesTable:

 

...

TableCell cellOperations;

// declare the new HyperLink control

HyperLink linkRename;

...

 

foreach (DirectoryInfo childDir in childDirs)

{  

  ...

  cellOperations = new TableCell();

  // create the new link

  linkRename = new HyperLink();

           

  // create the other columns and controls

  ...

 

  // add the Rename link. The 'D' before the file location

  // will be used to determine that the path identifies a directory

  linkRename.Text = "<img src=\"./Images/Rename.gif\" border=\"0\ +

      " height=\"16\" width=\"16\" Alt=\"Rename\">";

  linkRename.NavigateUrl = "javascript:Rename('D" + location + "');";

  cellOperations.Controls.Add(linkRename);

 

  // add the cells to the new row

  rowItem.Cells.Add(cellItemIcon);

  rowItem.Cells.Add(cellItemLink);

  rowItem.Cells.Add(new TableCell());


  rowItem.Cells.Add(cellOperations);

  rowItem.Cells.Add(cellAttributes);

  rowItem.Cells.Add(cellSize);

  rowItem.Cells.Add(cellCreated);

  rowItem.Cells.Add(cellLastModified);

   

  // add the new row to the table

  rowItem.ApplyStyle(styleFolderRow);

  FoldersAndFiles.Rows.Add(rowItem);

}

 

// now add each child file

foreach (FileInfo childFile in childFiles)

{

  ...

  cellOperations = new TableCell ();

  // create the new link

  linkRename = new HyperLink();

         

  // create the other columns and controls

  ...

   

  // add the Rename link. The 'F' before the file location will be used

  // to determine that the path identifies a file

  linkRename.Text = "<img src=\"./Images/Rename.gif\" border=\"0\ +

      " height=\"16\" width=\"16\" Alt=\"Rename\">";

  linkRename.NavigateUrl = "javascript:Rename('F" + location + "');";

  cellOperations.Controls.Add(linkRename);

   

  // add the Edit File icon, if the file is write-enabled

  ...

 

  // add the cells to the new row, and add the row

  ...

}

 

The only peculiarity in the code above is that a 'D' or 'F' letter is added to the path passed to the JavaScript Rename function. The whole string will then be passed to the server event handler, which will determine if the path identifies a file or a folder by extracting the first letter. This is, of course, necessary because there are two different classes – one for working with folders and one for files.

 

You can see this in the following procedure:

 

protected void Rename_Click(object sender, EventArgs e)

{

  // the first char of the first param is F if the path identifies a file,

  // D otherwise. Extract the first char to determine this

  bool isFile = funcParam.Value.StartsWith("F");

  // extract the source path

  string sourcePath = Server.MapPath(funcParam.Value.Substring(1));

  string destPath;

 

  try


  {

    if (isFile)

    {

      FileInfo sourceFile = new FileInfo(sourcePath);

      // create the destination path: source path dir + new name

      destPath = Path.Combine(sourceFile.Directory.FullName, +

           funcExtraParam.Value);

      // move the file = rename

      sourceFile.MoveTo(destPath);

    }

    else

    {

      DirectoryInfo sourceDir = new DirectoryInfo(sourcePath);

      // create the destination path: source path dir + new name

      destPath = Path.Combine(sourceDir.Parent.FullName, +

          funcExtraParam.Value);

      // move the directory = rename

      sourceDir.MoveTo(destPath);

    }

    // refresh the page

    Response.Redirect("BrowseFiles.aspx?Folder=" + folderPath);

  }

  catch (Exception exc)

  {

    StatusMessage.Text = exc.Message;

    StatusMessage.Visible = true;

  }

}

 

The item is moved to the current path but with a different name, therefore it is renamed. At the end of the procedure, if no exceptions have been raised, the table is filled with the updated content. The exception handling is very important here: you may have loaded the page with the list of files fifteen minutes ago, and in the meantime another administrator might have deleted or moved some files. But you still see the old content as long as you don't refresh the page, and if you try to rename a file/directory that no longer exists an exception will be generated. In that case it is handled and a message explaining the problem is shown.


DevASP.Net - Disclaimer - Privacy
Copyright © 2008 DevASP.net