Recursive File List Control v2 (ASP.NET)
Much like the original Recursive File List Control, this user control lists files and folders within a virtual web folder. Improvements include - excludes directories ending in '_file' (i.e. those created by Internet Explorer when you download a web page), excludes files beginning with '~$' (i.e. temporary documents generated by Microsoft Office applications), multiple instances can be placed on a web page, postback does not end up causing duplication of list and it takes into account other querystring parameters that may be passed on to the page.
Control (filelist.ascx)
<%@ Control Language="C#" src="filelist.ascx.cs" Inherits="WebDeveloperBlog.RecursiveFileList" %>
Code behind (filelist.ascx.cs)
using System; using System.Collections; using System.Collections.Specialized; using System.IO; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace WebDeveloperBlog { public class RecursiveFileList : UserControl { protected HyperLink lnkReset; protected Literal FileList; /// <summary> /// The virtual folder is the initial folder to start with, default root of application, but can be overridden by calling page /// </summary> public string VirtualFolder { get { if (ViewState["virtualFolder"]==null) { ViewState["virtualFolder"] = "~/"; } return ViewState["virtualFolder"].ToString(); } set { ViewState["virtualFolder"] = value; } } /// <summary> /// List of file types to show. Set up in the Control_Load function /// </summary> private ArrayList fileTypes = new ArrayList(); /// <summary> /// For internal use only /// </summary> private ArrayList folders; /// <summary> /// List of folders to be show files/folders in /// </summary> protected ArrayList Folders { get { if (folders == null) { if (UrlPathInfo != null) { folders = new ArrayList(UrlPathInfo.Split(';')); } else { folders = new ArrayList(); } } return folders; } set { folders = value; } } /// <summary> /// The path to the aspx page calling this control /// </summary> private string UrlPath { get { return HttpContext.Current.Request.Path; } } /// <summary> /// The folders that are to be filtered. Used getting the folders from the Folders array list /// </summary> private string UrlPathInfo { get { return HttpContext.Current.Request.QueryString[FilterFolderParameter]; } } /// <summary> /// The query parameter to use when checking which folders to display the folder/file contents of /// </summary> private string FilterFolderParameter { get { return this.ClientID.ToString() + "folders"; } } /// <summary> /// Builds a list of folders from the Folders array list using ; as the deliminator /// </summary> private string BuildFolderList { get { string strList = string.Empty; for(int i=0; i<Folders.Count; i++) { strList += HttpContext.Current.Server.UrlEncode(Folders[i].ToString()) + ";"; } if (strList != string.Empty) { strList = strList.Substring(0, strList.LastIndexOf(';')); } return strList; } } #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(); } /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.Load += new System.EventHandler(this.Control_Load); } #endregion private void Control_Load(object sender, EventArgs e) { // add file types fileTypes.Add("doc"); fileTypes.Add("rtf"); fileTypes.Add("xls"); fileTypes.Add("pdf"); // add reset list link if not already added if (lnkReset == null) { lnkReset = new HyperLink(); lnkReset.Text = "Reset list '" + VirtualFolder + "'"; this.Controls.Add(lnkReset); } // set result link to path of current page string resetUrl = UrlPath; NameValueCollection q = new NameValueCollection(HttpContext.Current.Request.QueryString); q.Remove(FilterFolderParameter); for (int i = 0; i <= q.Count - 1; i++) { if (i != 0) { resetUrl += "&"; } else { resetUrl += "?"; } resetUrl += q.GetKey(i) + "=" + q.Get(i); } lnkReset.NavigateUrl = resetUrl; // add file list Literal control if not on page if (FileList == null) { FileList = new Literal(); this.Controls.Add(FileList); } // recurse folder starting with the supplied virtual folder if (!Page.IsPostBack) { RecurseFolders(VirtualFolder); } } /// <summary> /// Check if in Folders array list /// </summary> private bool InFolders(string s) { for(int i=0; i<Folders.Count; i++) { if(Folders[i].ToString() == s) { return true; } } return false; } /// <summary> /// Check if file is one that is allowed /// </summary> private bool AllowedFileType(string fileExt) { for(int i=0; i<fileTypes.Count; i++) { if(fileTypes[i].ToString() == fileExt.ToLower()) { return true; } } return false; } /// <summary> /// Recurse folders in path, excluding those that aren't in the Folders array list /// </summary> private void RecurseFolders(string path) { // Open the list FileList.Text += "<ul>"; string mappedRoot = HttpContext.Current.Server.MapPath(path); HttpContext.Current.Trace.Write("WebDeveloperBlog.RecursiveFileList", "Folder: " + mappedRoot); string[] folders = null; try { folders = Directory.GetDirectories(mappedRoot); // Iterate through each folder foreach (string folder in folders) { // ignore folders ending in _files (these are folders used when saving web pages from Internet Explorer) if (folder.Substring(folder.Length - 6) == "_files") { continue; } string virtfolder = folder.Replace(mappedRoot, string.Empty); string subFolder = path + virtfolder + "/"; string[] subfolders = Directory.GetDirectories(folder); string[] files = Directory.GetFiles(folder); string whichfolders = string.Empty; HttpContext.Current.Trace.Write("WebDeveloperBlog.RecursiveFileList", folder + "\n Sub folder count: " + subfolders.Length + "\n File count: " + files.Length); if (InFolders(subFolder)) { Folders.Remove(subFolder); whichfolders = BuildFolderList; Folders.Add(subFolder); } else { Folders.Add(subFolder); whichfolders = BuildFolderList; Folders.Remove(subFolder); } NameValueCollection q = new NameValueCollection(HttpContext.Current.Request.QueryString); q[FilterFolderParameter] = whichfolders; if (q[FilterFolderParameter] == string.Empty) { q.Remove(FilterFolderParameter); } FileList.Text += "<li><a href=\"" + UrlPath; for (int i = 0; i <= q.Count - 1; i++) { if (i != 0) { FileList.Text += "&"; } else { FileList.Text += "?"; } FileList.Text += q.GetKey(i) + "=" + q.Get(i); } FileList.Text += "\">" + HttpContext.Current.Server.HtmlEncode(virtfolder) + "</a>"; if (InFolders(subFolder)) { // recurse sub folder FileList.Text += Environment.NewLine; RecurseFolders(subFolder); } FileList.Text += "</li>" + Environment.NewLine; } } catch (System.Exception ex) { HttpContext.Current.Trace.Warn("WebDeveloperBlog.RecursiveFileList", ex.Source, ex); } try { string[] files = Directory.GetFiles(mappedRoot); // Iterate through the files in this folder if(files.Length == 0) { if (folders.Length == 0) { FileList.Text += "<li>No files</li>" + Environment.NewLine; } } else { foreach (string file in files) { string fileName = file.Replace(mappedRoot, string.Empty); // ignore files beginning with ~$ (these are files generated by Microsoft Office applications) if (fileName.Substring(0,2) == "~$") { continue; } if (!AllowedFileType(GetExt(fileName))) continue; // link to file FileList.Text += "<li> File: " + "<a href=\"" + path + fileName + "\">" + HttpContext.Current.Server.HtmlEncode(RemoveExt(fileName)) + "</a></li>"; // Put the fileName in the textbox FileList.Text += Environment.NewLine; } } } catch (System.Exception ex) { HttpContext.Current.Trace.Warn("WebDeveloperBlog.RecursiveFileList", ex.Source, ex); } // Close the list FileList.Text += "</ul>" + Environment.NewLine; } /// <summary> /// Remove file extension from the supplied file name /// </summary> private string RemoveExt(string fileName) { return fileName.Substring(0,fileName.LastIndexOf('.')); } /// <summary> /// Get the extension from the supplied file name /// </summary> private string GetExt(string fileName) { int dot = fileName.LastIndexOf('.') + 1; return fileName.Substring(dot, fileName.Length - dot); } } }
Sample page (filelist.aspx)
<%@ Page Language="C#" Trace="False" ContentType="text/html" ResponseEncoding="iso-8859-1" %> <%@ Register TagPrefix="Files" TagName="List" Src="filelist.ascx" %> <html> <head> <title>File listing</title> </head> <body> <form runat="server"> <Files:List runat="server" VirtualFolder="/virtualdir/" /> <Files:List runat="server" VirtualFolder="/virtualdir2/" /> </form> </body> </html>
Tags: Web Developer Blog, ASP.NET, CSharp
Comments