Click here to Skip to main content
15,880,956 members
Articles / Web Development / ASP.NET
Article

Web File Manager

Rate me:
Please Sign up or sign in to vote.
4.79/5 (66 votes)
9 Jan 20055 min read 539.5K   16.3K   220   129
A single page ASP.NET file management utility.

Sample Image - WebFileManager.gif

Introduction

I often deploy ASP.NET websites to servers that I don't control. In these situations, I can't get to the underlying file system to do any file maintenance, because I don't have direct access to the server. So I have to access the file system indirectly, through the website that I am deploying. Rather than writing a bunch of special purpose pages to deal with file management, I developed a generic WebFileManager page than can be dropped into any ASP.NET website. This page performs the most common file and folder operations:

  • Uploading
  • Deleting
  • Renaming
  • Copying
  • Zipping
  • Moving

Adding WebFileManager to an existing ASP.NET project is relatively straightforward. It can be done in one of two ways:

Deployment as Inline Code

The first method, and I think the easiest, is to deploy the inline code version of WebFileManager: default-inline.aspx. Make a copy of this file and rename it default.aspx. Copy the WebFileManager folder to your web server. This folder only needs the following files:

  • \WebFileManager\default.aspx (renamed from default-inline.aspx)
  • \WebFileManager\images\file\*.gif
  • \WebFileManager\images\icon\*.gif

And you're done! The main advantage of this approach is that it doesn't require any changes to Web.config and thus doesn't force the app to restart. The downside is that the inline version of the page must be converted from the code-behind master; inline pages are a pain to debug and maintain.

Deployment as Code-Behind

If you're more comfortable with a typical code-behind page, that can also be deployed relatively easily: default.aspx is the master, code-behind version of WebFileManager.

  1. Copy the WebFileManager folder to your web server. This folder only needs the following files:
    • \WebFileManager\default.aspx
    • \WebFileManager\bin\WebFileManager.dll
    • \WebFileManager\images\file\*.gif
    • \WebFileManager\images\icon\*.gif
  2. Because code-behind generates a separate assembly DLL, you have to let the main webapp know where to find this file. Modify Web.config as follows:
    XML
    <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <probing 
         privatePath="http://www.codeproject.com/useritems/WebFileManager/bin" />
      </assemblyBinding>
    </runtime>
  3. The page should now load using all default settings. If you want to override the defaults, see the configuration table later in this article for additional Web.config keys.

Whichever method of deployment you use, the new ZIP functionality requires ICSharpCode.SharpZipLib.dll to be present somewhere. I find that most of my web projects have this dependency already, but your mileage may vary. If you don't want this dependency, you'll need to comment out the ZIP code in the source. It's all in one function, so it isn't hard to remove.

Things to watch out for

Bear in mind that file system operations will occur as the ASP.NET process account by default (machinename\ASPNET), not as the user accessing the page! Any permission errors during a file operation will be trapped and echoed at the top of the page. So if you're wondering "Why can't I upload a file?" or "Why can't I delete that annoying folder?", it's typically because the ASPNET account doesn't have enough filesystem permissions to do so.

It's not included in the sample project, but there are a couple of reasons why you may also want to create a custom, local \WebFileManager\Web.config file:

  • If you want file operations to occur as a specific user: enable impersonation.
  • If you want to restrict access: set authorization.

Don't forget that web.config settings work fine on a per-folder basis, which is ideal for this purpose-- you can grant access to only a few users, or have the entire page run as administrator, without affecting the rest of the website.

Implementation

I'll warn you up front: this page is not a model of proper ASP.NET design. It uses Response.Write extensively, and does not use a single server control. I kept it deliberately old school, because I wanted a minimal amount of code and tight control of the HTML produced. I don't recommend this approach for a larger project, but I think it's OK for a single utility page.

As for the code, there is a handful of static HTML in default.aspx, and an associated code-behind class. The static HTML contains some JavaScript and a basic stylesheet, as well as the HTML page template. The page body, however, is rendered by the WriteTable method.

The main loop is very straightforward: it iterates through every directory and file in the current directory, and copies that to a simple DataTable structure, which is then sorted into a DataView and dumped to the output buffer in a simplified table format. The table is designed to render progressively using the "table-layout:fixed" style attribute:

VB
With Response
  .Write("<TR>")
  .Write("<TD align=right><INPUT name=""")
  .Write(_strCheckboxTag)
  .Write(strFileName)
  .Write(""" type=checkbox>")
  .Write("<TD align=center><IMG src=""")
  .Write(FileIconLookup(drv))
  .Write(""" ")
  .Write(_strIconSize)
  .Write(">")
  .Write("<TD>")
  .Write(strFileLink)
  .Write("<TD align=right>")
  If blnFolder Then
    .Write("<TD align=left>")
  Else
    .Write(FormatKB(Convert.ToInt64(drv.Item("Size"))))
    .Write("<TD align=left>kb")
  End If
  .Write("<TD align=right>")
  .Write(Convert.ToString(drv.Item("Created")))
  .Write("<TD align=right>")
  .Write(Convert.ToString(drv.Item("Modified")))
  .Write("<TD align=right>")
  .Write(Convert.ToString(drv.Item("Attr")))
  .Write(Environment.NewLine)
End With
Flush()

File and folder operations are triggered by the checkboxes next to each row and a hidden form field with an action string. The JavaScript functions do some basic client-side error checking, set the action form field appropriately, and submit the form. On postback, the HandleAction method is called:

VB
Public Sub HandleAction()
    If Request.Form(_strActionTag) Is Nothing Then Return

    Dim strAction As String = Request.Form(_strActionTag).ToLower
    If strAction = "" Then Return

    Select Case strAction
        Case "newfolder"
            MakeFolder(GetTargetPath)
        Case "upload"
            SaveUploadedFile()
        Case Else
            ProcessCheckedFiles(strAction)
    End Select
    If Not _FileOperationException Is Nothing Then
        WriteError(_FileOperationException)
    End If
End Sub

I am capturing any file operation failures into a class level variable _FileOperationException. If a file delete fails because the ASPNET process doesn't have access to it, we just want to display a simple message-- not throw a massive exception all the way up to the main application.

Configuration

This page does have a few configuration options it looks for in Web.config. These are all optional.

XML
<add key="WebFileManager/ImagePath" 
        value= "resources/WebFileManager/images/" />
<add key="WebFileManager/HideFolderPattern" 
        value= "^bin|test" />
<add key="WebFileManager/HideFilePattern" 
        value= "scc$" />
<add key="WebFileManager/AllowedPathPattern" 
        value= "/MyWeb/Uploads/.*" />
<add key="WebFileManager/DefaultPath" 
        value= "~/MyWeb/Uploads" />
PropertyDefaultDescription
ImagePath"images/"Root-relative path to the file/*.gif and icon/*.gif images used on the page.
HideFolderPattern""Folder names matching this regular expression will not be displayed.
HideFilePattern""File names matching this regular expression will not be displayed
AllowedPathPattern""The user will only be allowed to navigate to paths that match this pattern.
DefaultPath"~/"Default path that will be displayed if no path is specified in the path= QueryString.
FlushContentFalseIssue a Response.Flush after writing each table row. Renders faster, but some HttpModules don't work with partial content.

Conclusion

WebFileManager is a simple page, but it has worked well for me in a number of projects. Hopefully, it'll work for you too.

There are many more details and comments in the demonstration solution provided at the top of the article, so check it out. And please don't hesitate to provide feedback, good or bad! I hope you enjoyed this article. If you did, you may also like my other articles as well.

History

  • Friday, November 26, 2004 - published
  • Wednesday, January 5, 2005 - Version 1.1
    • Added persistent up/down column sorting by clicking column headers
    • Default sort is now by name instead of "as returned by .NET functions"
    • Added ability to ZIP files using SharpZipLib
    • Improved FireFox support (FireFox doesn't support <COLGROUP> alignments?!)
    • Move and Copy now create destination folders if it doesn't exist.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
My name is Jeff Atwood. I live in Berkeley, CA with my wife, two cats, and far more computers than I care to mention. My first computer was the Texas Instruments TI-99/4a. I've been a Microsoft Windows developer since 1992; primarily in VB. I am particularly interested in best practices and human factors in software development, as represented in my recommended developer reading list. I also have a coding and human factors related blog at www.codinghorror.com.

Comments and Discussions

 
GeneralThanks for sharing Pin
Sabarinathan A30-Sep-09 19:46
professionalSabarinathan A30-Sep-09 19:46 
Generalnow broke under .Net Framework 3.5 w/ scriptmanager Pin
disdp128-Nov-08 3:49
disdp128-Nov-08 3:49 
GeneralRe: now broke under .Net Framework 3.5 w/ scriptmanager Pin
Paul /)/+)22-Jan-10 1:56
Paul /)/+)22-Jan-10 1:56 
GeneralRe: now broke under .Net Framework 3.5 w/ scriptmanager Pin
simoness21-Dec-10 13:26
simoness21-Dec-10 13:26 
Generaljust thanks Pin
dahlheim22-Sep-08 6:00
dahlheim22-Sep-08 6:00 
GeneralThe Unzip code has an error Pin
OsamaT8-Aug-08 23:00
OsamaT8-Aug-08 23:00 
GeneralRe: The Unzip code has an error Pin
Emagine16-Apr-10 4:11
Emagine16-Apr-10 4:11 
QuestionHow to include File versioning Pin
Member 122895329-Jun-08 17:57
Member 122895329-Jun-08 17:57 
Is it possible to also include File versioning management into this ? Is there any sample code to acheive this ?
GeneralWebFileManager.dll is not existing in "bin" Pin
kengkit120826-Jun-08 19:19
kengkit120826-Jun-08 19:19 
Questionmanager to transfer directories from a storage server to a local hard drive? Pin
robert hill3-Mar-08 15:47
robert hill3-Mar-08 15:47 
QuestionHow do I change the web root? Pin
Darin Spence14-Dec-07 6:33
Darin Spence14-Dec-07 6:33 
QuestionCompiler Error Message: BC30002 Pin
Darin Spence12-Dec-07 17:41
Darin Spence12-Dec-07 17:41 
GeneralRe: Compiler Error Message: BC30002 Pin
Darin Spence14-Dec-07 6:05
Darin Spence14-Dec-07 6:05 
QuestionRe: Compiler Error Message: BC30002 Pin
gayatri54@yahoo.com4-Jun-08 11:02
gayatri54@yahoo.com4-Jun-08 11:02 
AnswerRe: Compiler Error Message: BC30002 Pin
ImamKD15-Nov-08 2:56
ImamKD15-Nov-08 2:56 
GeneralCould be nicer if no physical folders were created! Pin
azamsharp14-Oct-07 15:36
azamsharp14-Oct-07 15:36 
QuestionSession variables lost when a folder is renamed Pin
Alex-M5-Oct-07 10:22
Alex-M5-Oct-07 10:22 
AnswerRe: Session variables lost when a folder is renamed Pin
peebee25-Nov-07 11:52
peebee25-Nov-07 11:52 
GeneralRe: Session variables lost when a folder is renamed Pin
TheFrnd27-Jan-08 1:42
TheFrnd27-Jan-08 1:42 
GeneralMessage Closed Pin
16-Apr-10 4:06
Emagine16-Apr-10 4:06 
QuestionAccess Networked Directories Pin
Aarrtishe6-Jul-07 18:39
Aarrtishe6-Jul-07 18:39 
AnswerRe: Access Networked Directories Pin
Member 24982213-Apr-09 5:04
Member 24982213-Apr-09 5:04 
AnswerMessage Closed Pin
16-Apr-10 4:08
Emagine16-Apr-10 4:08 
GeneralModified code with UNZIP capabilities Pin
mdirienzo27-Mar-07 5:25
mdirienzo27-Mar-07 5:25 
GeneralHUGE Security FLAW Pin
dontpntpool8-Dec-06 9:38
dontpntpool8-Dec-06 9:38 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.