|
|||||||||||||||||||||
|
|||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
Introduction
I guess most of us are still on the pre-.NET mindset, the term I commonly use when people think of solutions that are based on the ways of doing stuff without utilizing the benefits of the new technology which could help in making the task a lot easier. A great example of this type of mindset is this, what comes to your mind when you are asked to create a Web Form that enables the user to list the contents of a folder and enables the user to download selected files on that folder? I bet you more than 80% of the programmers would have this answer.
Guilty?? I guess most of us still think this way... What if I tell you that you can do this task by just using some Here is the C# example of the classic code: 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.Text;
using System.IO;
using System.Configuration;
namespace KeithRull.FolderBrowserCS
{
/// <summary>
/// Summary description for FolderBrowser.
/// </summary>
public class theOldWayBrowser : System.Web.UI.Page
{
protected System.Web.UI.WebControls.PlaceHolder plhFiles;
private void Page_Load(object sender, System.EventArgs e)
{
//create the our table
LiteralControl lcTableHead = new
LiteralControl(@"<TABLE id=FileSystem" +
@"style='FONT-SIZE: xx-small;" +
@"BORDER-TOP-STYLE: none;" +
@"FONT-FAMILY: Arial;" +
@"BORDER-RIGHT-STYLE: none;" +
@"BORDER-LEFT-STYLE: none;" +
@"BORDER-COLLAPSE: collapse;" +
@"BORDER-BOTTOM-STYLE: none'" +
@"cellSpacing=0" +
@"rules=all border=1>");
plhFiles.Controls.Add(lcTableHead);
LiteralControl lcContents;
//creathe the column headers
LiteralControl lcTableHeader = new
LiteralControl(@"<TR>" +
@"<TD style='WIDTH: 80px'>Type</TD>" +
@"<TD style='WIDTH: 350px'>Name</TD>" +
@"<TD style='WIDTH: 150px'>CreationTime</TD>" +
@"<TD style='WIDTH: 150px'>LastWriteTime</TD>" +
@"</TR>");
plhFiles.Controls.Add(lcTableHeader);
try
{
//read our query string, if its null,
//assign the default folder
//to our variable else assign the query string value.
string strDir = Request.QueryString["d"] == null ?
FileBrowerProperty.IntialPath : Request.QueryString["d"];
//read the directory
DirectoryInfo DirInfo = new DirectoryInfo(strDir);
//read the subdirectories inside the parent directory
DirectoryInfo[] subDirs = DirInfo.GetDirectories();
//read the files in the parent directory
FileInfo[] Files = DirInfo.GetFiles();
//check if there are directories and
//files inside our parent directory
if((Files.Length != 0) && (subDirs.Length!=0))
{
//loop thru each of the directory
//inside the parent directory
foreach(DirectoryInfo di in subDirs)
{
//add the directory info to our table
LiteralControl lcFolders =
new LiteralControl(@"<TR>" +
@"<TD style='WIDTH: 80px'>" +
@"Directory</TD>" +
@"<TD style='WIDTH: 350px'>" +
@"<a href='theOldWayBrowser.aspx?d=" +
@di.FullName + "'>" + di.Name +
"</a></TD><TD style='WIDTH: 150px'>" +
di.CreationTime +
"</TD><TD style='WIDTH: 150px'>" +
di.LastWriteTime + "</TD></TR>");
plhFiles.Controls.Add(lcFolders);
}
//loop thru each of the file
//inside the parent directory
foreach(FileInfo fi in Files)
{
//add the file info to our table
LiteralControl lcContentsHead =
new LiteralControl("<tr><td>File</td><td>");
plhFiles.Controls.Add(lcContentsHead);
LinkButton lb = new LinkButton();
//set the label and command name
//to the filename of the file
lb.Text = @fi.Name;
lb.CommandName = @fi.Name;
//set the command argument to the fullpath
lb.CommandArgument = @fi.FullName;
//add our handler
lb.Click += new EventHandler(Download);
plhFiles.Controls.Add(lb);
LiteralControl lcContentsTail =
new LiteralControl("</td><td>" +
fi.CreationTime +
"</td><td valign='bottom'>"+
fi.LastWriteTime+"</td></tr>");
plhFiles.Controls.Add(lcContentsTail);
}
}
else
{
// there is file or folder inside the directory
lcContents =
new LiteralControl("<tr>" +
"<td colspan = 4>" +
"No file/folder found inside this " +
"directory.</td></tr>");
plhFiles.Controls.Add(lcContents);
}
}
catch(Exception ex)
{
//error trap
lcContents =
new LiteralControl("<tr>" +
"<td colspan = 4> Error encountered" +
" while trying to parse directory. " +
ex.Message + "</td></tr>");
plhFiles.Controls.Add(lcContents);
}
LiteralControl lcTableTail =
new LiteralControl("</table>");
plhFiles.Controls.Add(lcTableTail);
}
private void Download(object sender, System.EventArgs e)
{
//get the file path
string filepath = ((LinkButton) sender).CommandArgument;
//geth the filename
string filename = ((LinkButton) sender).CommandName;
//read the file to our stream
Stream s = File.OpenRead(filepath);
//create the bytes to be streamed
Byte[] buffer = new Byte[s.Length];
//build the buffer
try
{
s.Read(buffer, 0, (Int32) s.Length);
}
//close our stream
finally { s.Close(); }
//clear the response headers
Response.ClearHeaders();
//clear the content type
Response.ClearContent();
Response.ContentType = "application/octet-stream";
//add our header
Response.AddHeader("Content-Disposition",
"attachment; filename=" + filename);
//write the buffer to the http stream
Response.BinaryWrite(buffer);
//end response
Response.End();
}
}
}
Doesn't this look like an old ASP implementation? Working with the interface while reading the data? As I said a while ago, we can accomplish the same task by using The The listing below shows how to list the contents of a folder using private void Page_Load(object sender, System.EventArgs e)
{
string folderToBrowse = @"c:\";
DirectoryInfo DirInfo =
new DirectoryInfo(folderToBrowse);
FileSystemGrid.DataSource =
DirInfo.GetFileSystemInfos();
FileSystemGrid.DataBind();
}
Please take a note that you need to setup your grid to accept the values that are generated by the <asp:datagrid id="FileSystemGrid" runat="server"
BorderStyle="None" AutoGenerateColumns="False"
Font-Size="XX-Small" Font-Names="Arial"
AllowSorting="True">
<Columns>
<asp:TemplateColumn HeaderText="Name">
<HeaderStyle Width="350px"></HeaderStyle>
<ItemTemplate>
<asp:HyperLink id=systemLink runat="server" NavigateUrl=''
Text='<%# DataBinder.Eval(Container, "DataItem.FullName") %>'>
</asp:HyperLink>
</ItemTemplate>
</asp:TemplateColumn>
<asp:BoundColumn DataField="CreationTime"
HeaderText="CreationTime">
<HeaderStyle Width="150px"></HeaderStyle>
</asp:BoundColumn>
<asp:BoundColumn DataField="LastWriteTime"
HeaderText="LastWriteTime">
<HeaderStyle Width="150px"></HeaderStyle>
</asp:BoundColumn>
</Columns>
</asp:datagrid>
The result of our first sample is shown below:
This is simple? right? What if we want to add some user interactions? For example, clicking on a selected directory would allow the user to browse the underlying files and directories. To accomplish this task, we need to have a Here is the C# example of the solution to this problem: 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 KeithRull.FolderBrowserCS
{
/// <summary>
/// Summary description for theNewWayBrowser.
/// </summary>
public class theNewWayBrowser : System.Web.UI.Page
{
protected System.Web.UI.WebControls.DataGrid FileSystem;
private void Page_Load(object sender, System.EventArgs e)
{
//read our query string, if its null, assign the default folder
//to our variable else assign the query string value.
string folderToBrowse = Request.QueryString["d"] == null ?
FileBrowerProperty.IntialPath : Request.QueryString["d"];
//read the folder
DirectoryInfo DirInfo = new DirectoryInfo(folderToBrowse);
//create our datatable that would hold the list
//of folders in the specified directory
DataTable fileSystemFolderTable = new DataTable();
//create our datatable that would hold the list
//of files in the specified directory
DataTable fileSystemFileTable = new DataTable();
//create our datatable that would hold the list
//of files and folders when we combine the two
//previously declared datatable
DataTable fileSystemCombinedTable = new DataTable();
//create the columns for our file datatable
DataColumn dcFileType = new DataColumn("Type");
DataColumn dcFileFullName = new DataColumn("FullName");
DataColumn dcFileName = new DataColumn("Name");
DataColumn dcFileCreationTime = new DataColumn("CreationTime");
DataColumn dcFileLastWriteTime = new DataColumn("LastWriteTime");
//create the columns for our folder datatable
DataColumn dcFolderType = new DataColumn("Type");
DataColumn dcFolderFullName = new DataColumn("FullName");
DataColumn dcFolderName = new DataColumn("Name");
DataColumn dcFolderCreationTime = new DataColumn("CreationTime");
DataColumn dcFolderLastWriteTime = new DataColumn("LastWriteTime");
//add the columns to our datatable
fileSystemFolderTable.Columns.Add(dcFileType);
fileSystemFolderTable.Columns.Add(dcFileName);
fileSystemFolderTable.Columns.Add(dcFileFullName);
fileSystemFolderTable.Columns.Add(dcFileCreationTime);
fileSystemFolderTable.Columns.Add(dcFileLastWriteTime);
fileSystemFileTable.Columns.Add(dcFolderType);
fileSystemFileTable.Columns.Add(dcFolderName);
fileSystemFileTable.Columns.Add(dcFolderFullName);
fileSystemFileTable.Columns.Add(dcFolderCreationTime);
fileSystemFileTable.Columns.Add(dcFolderLastWriteTime);
//loop thru each directoryinfo object in the specified directory
foreach(DirectoryInfo di in DirInfo.GetDirectories())
{
//create a new row in ould folder table
DataRow fileSystemRow = fileSystemFolderTable.NewRow();
//assign the values to our table members
fileSystemRow["Type"] = "Directory";
fileSystemRow["Name"] = di.Name;
fileSystemRow["FullName"] = di.FullName;
fileSystemRow["CreationTime"] = di.CreationTime;
fileSystemRow["LastWriteTime"] = di.LastWriteTime;
fileSystemFolderTable.Rows.Add(fileSystemRow);
}
//loop thru each fileinfo object in the specified directory
foreach(FileInfo fi in DirInfo.GetFiles())
{
//create a new row in ould folder table
DataRow fileSystemRow = fileSystemFileTable.NewRow();
//assign the values to our table members
fileSystemRow["Type"] = "File";
fileSystemRow["Name"] = fi.Name;
fileSystemRow["FullName"] = fi.FullName;
fileSystemRow["CreationTime"] = fi.CreationTime;
fileSystemRow["LastWriteTime"] = fi.LastWriteTime;
fileSystemFileTable.Rows.Add(fileSystemRow);
}
//copy the folder table to our main datatable,
//this is necessary so that the parent table would have the
//schema of our child tables.
fileSystemCombinedTable = fileSystemFolderTable.Copy();
//loop thru each row of our file table
foreach(DataRow drw in fileSystemFileTable.Rows)
{
//import the rows from our child table to the parent table
fileSystemCombinedTable.ImportRow(drw);
}
//assign our file system parent table to our grid and bind it.
FileSystem.DataSource = fileSystemCombinedTable;
FileSystem.DataBind();
}
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required
// by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.FileSystem.ItemCommand +=
new DataGridCommandEventHandler(FileSystem_ItemCommand);
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
private void FileSystem_ItemCommand(object source,
DataGridCommandEventArgs e)
{
//get the filepath from the specified
//command arguments for our linkbutton
string filepath = e.CommandArgument.ToString();
//get the file system type of the selected ite
string fileSystemType =
FileSystem.Items[e.Item.ItemIndex].Cells[0].Text;
//if its a directory, redirect to our page and passing
//the new file path to our query string
if(fileSystemType == "Directory")
{
Response.Redirect("theNewWayBrowser.aspx?d="+
e.CommandArgument.ToString());
}
else
{
//get the filename
string filename = e.CommandName;
//read the file to our stream
Stream s = File.OpenRead(filepath);
//create the bytes to be streamed
Byte[] buffer = new Byte[s.Length];
//build the buffer
try {
s.Read(buffer, 0, (Int32) s.Length);
}
//close our stream
finally { s.Close(); }
//clear the response headers
Response.ClearHeaders();
//clear the content type
Response.ClearContent();
Response.ContentType = "application/octet-stream";
//add our header
Response.AddHeader("Content-Disposition",
"attachment; filename=" + filename);
//write the buffer to the http stream
Response.BinaryWrite(buffer);
//end response
Response.End();
}
}
}
}
The screenshot of the result of our solution is shown below:
As you can see, we have accomplished the same result as the first example that uses the legacy ASP logic using native ASP.NET objects. | ||||||||||||||||||||