
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.
- 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
- 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:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing
privatePath="http://www.codeproject.com/useritems/WebFileManager/bin" />
</assemblyBinding>
</runtime>
- 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:
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:
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.
<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" />
| Property |
Default |
Description |
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. |
FlushContent |
False |
Issue 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.
| You must Sign In to use this message board. |
|
|
 |
|
 |
"Excellent" rating from me
Sabarinathan Arthanari As a child of God (Truth/Love), I am greater than anything that can happen to me -Dr APJ Abdul Kalam.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Jeff,
To date this has been a wonderful tool you provided. But, recently I updated to VS2008 and the Framework to 3.5.
The webfilemanager has ceased to work when adding a scriptmanager. All document.forms[0].submit() events result in a HTTP Error 400 - Bad Request.
Any insite into this issue issue would be appreciated. I've been working on the error for some time and that's why I'm posting here. If I find a solution, I'll add a new message.
Dave P
|
| Sign In·View Thread·PermaLink | 3.00/5 |
|
|
|
 |
|
 |
just a thanks to the author. i implemented the code into my site (inline) with minimal editing for my purposes, just a private site so that a few partners can easily maintain a file area. thanks alot, saved me a lot of time!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hello.. thank yo for the nice code. your a life saver. but
the unzip code is not perfect. when you upload some files to the webserver and then zip them .. then unzip them .. it works . but if you zip a collection of directories and files on your desktop then upload the zipped file to the webserver. try to unzip the file and it will unzip in C:\
any ideas why this is happening ?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Is it possible to also include File versioning management into this ? Is there any sample code to acheive this ?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
Thanks for your wonderful post.
I'm working on an asp.net department manager that includes a file management page to move media projects from unique directories on a file server to an edit drive on a local workstation. When users log into the manager, they need the capability to load their materials on any one of forty workstations, so their edit sessions don't have to take place a dedicated system. Their files reside in directories corresponding to their logins, and they shouldn't see past that directory on the server.
Is it possible to change the default root directory to accomplish this?
Thanks again for all your hard work. It helps open the eyes of those of us relatively new to asp.net.
|
| Sign In·View Thread·PermaLink | 1.00/5 |
|
|
|
 |
|
 |
This script is great, thank you!
I'm using in-line code, and don't want to put things in the web.config file. Is there a way that I can prevent the script from being able to traverse up to the web root ~/ ?
Right now, I have the script starting out in ~/Users/Username/Files/ If someone types ~/users/Username/Files/../../../ they can get to the web root.
|
| Sign In·View Thread·PermaLink | 1.50/5 |
|
|
|
 |
|
 |
Compiler Error Message: BC30002: Type 'ICSharpCode.SharpZipLib.Zip.ZipOutputStream' is not defined.
Just trying to run this in-line, looks cool. Here's the details:
Line 695: Line 696: Dim zfs As FileStream Line 697: Dim zs As ICSharpCode.SharpZipLib.Zip.ZipOutputStream Line 698: Try Line 699: If File.Exists(ZipTargetFile) Then
Source File: C:\inetpub\wwwroot\webfilemanager\default.aspx Line: 697
How do I make ICSharpCode.SharpZipLib.dll work?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
hmm... I have the file already in teh bin folder, works on local however when i put it on live server gives me an error .. Compiler Error Message: BC30002: Type 'ICSharpCode.SharpZipLib.Zip.ZipOutputStream' is not defined.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
You cant just copy that file to bin directory. But you must add reference from your project folder in Visual Studio (Right Click - Add Reference, then find your dll). It will make bin directory too, but it is differs from you made manually.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi,
This is a nice example of Web based file management system. Although one must look into developing a system where no actual folders are created on the file system and everything is virtual.
Thanks, Azam
Mohammad Azam azamsharp@gmail.com www.gridviewguy.com videos.gridviewguy.com
Houston, TEXAS
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi Jeff, thanks a lot for your article it`s really good. I just have one question about it; I added the web file manager to one of my projects, and when I was testing it, I rename one folder and then I realize that all my sessions variables have gone away. Do you know why does this happen?. I have been searching for this problem and seems to be a bug, check this link: http://blogs.msdn.com/tess/archive/2006/08/02/686373.aspx http://www.velocityreviews.com/forums/t75417-directorymovegt-sessions-lost.html
|
| Sign In·View Thread·PermaLink | 1.00/5 |
|
|
|
 |
|
 |
Alex- I have not tried this but I am guessing that is a side-effect of the ASP.NET worker process. When the ASP.NET worker process detects a change in the file system of an ASP app, it re-cycles. This causes your app cache and server side cache to be cleaned. So, if your app uses Application.Cache or Session.Cache then it is going to be blank the next time a page loads.
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
|
 |
|
 |
Hi
Thanks for the wonderful article. I want to modify Web File Manager so that the user can view the files and folders of the network as well.(e.g. the user enters //192.168.0.1/c$/Data and clicks Go). At Present an error messasge is displayed saying 'the file does not exist'. Please help.
Thanks in advance.
Aarrtishe
|
| Sign In·View Thread·PermaLink | 2.14/5 |
|
|
|
 |
|
 |
Hi Arrtishe
I have resolved this issue:
Replace following code with your existing code in code behind (this code will work for local file and network files)
Private Function GetLocalPath(Optional ByVal strFilename As String = "") As String If WebPath.Contains("//") Then 'It is network path Return Path.Combine(WebPath, strFilename) Else 'it is local path Return Path.Combine(Server.MapPath(WebPath), strFilename) End If End Function
Add following line in webconfig
100% Tested
Let me know if you have any question 
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
Do not use this code on the internet. As someone wrote previously this could can allow attackers to inject paths of their own.
The allowed path does nothing for someone that types /files/../ to get back out of the allowed area.
|
| Sign In·View Thread·PermaLink | 2.36/5 |
|
|
|
 |
|
 |
Tanx Jeff Really nice work done and very useful. But why have you not included the Download option in this.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi,
I am using ASP.NET 2.0 Web Express Edition, Everthing works perfect expect file upload. When I debug code,
If Request.Files.Count > 0 Then
above line alwasy return value 0 (Zero)...
Please help me to resolve this issue.
Thanks
Shrey
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 |
|
 |
I too am getting this error. I think it's due to the fact that I'm using MasterPages, and have server-side form in that page. That means this page's form is embedded inside of that form. I'd rather not have to add form tags to all of my pages, so if there's a quick fix, I'd love to know about it.
Thanks, Josh
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|