Saving Files to a Local Drive from ASP.NET

Joined
Feb 12, 2006
Messages
18
Location
Australia
Programming Experience
10+
My ASP.NET application (VS 2003 and VB.NET) has the ability to export files in csv format and I can auto-save them to the web server but what I really want to do is use the HTMLInputFile control to allow the user to enter a new filename and directory on their local hard disk. When I click the Browse button on the input control I'm not able to specify a new filename.

I've used this control before to successfully upload existing files from a local hard disk and store them in my SQL database but I can't see how to save a new file back to a local hard drive.

Does anyone know of a setting for the HTMLInputFile control that designates it as a "Save As" dialog rather than an "Open File" dialog?

I can read files back from the database which then gives me the option to Open or Save them but I want to avoid writing the file to the database first or even writing it to the web server if possible.

Hopefully this is not too hard?
 
You can not write to the local hard disk as this is considered as a security risk. Imagine you browse a website and it can access your HD. What if it writes some mallicious code onto your HD?

For every rule, there seems to be an exception though. You can get around this if you run some activeX controls but it's a real hassle to do that since it requires users interaction to install and set appropriate security permission unless you properly sign the control. And even with that, security policy might come into play and prevent the code from being execute at all.
 
Here's some code that opens a "Save As" dialog. In this example I'm getting the filename from a querystring but you should be able to adapt.
VB.NET:
Response.Clear()
Dim flnm as String = IO.Path.GetFileName(Request("URL"))
Response.AppendHeader("content-disposition", "attachment; filename=" & flnm)
Response.ContentType = "text/plain"
Response.WriteFile(Server.MapPath(New Uri(Request("URL")).LocalPath))
Response.Flush()
Response.End()
 
Only the simple things are hard!

It's been a while since I looked at this but no matter what I've tried I get the following error:

Access to the path "c:\inetpub\wwwroot\ScottQualityControl" is denied.

The aspnet account does have read/write access to this directory.

This occurs on the following code:

Response.Clear()
Dim DirectoryPath As String = "http://localhost/ScottQualityControl"
Dim Pagename As String = "FileCCN"
Dim FileAndPathName As String = DirectoryPath + System.Configuration.ConfigurationSettings.AppSettings("DefaultFileExportLocation") + _
System.Configuration.ConfigurationSettings.AppSettings(PageName) + _
Format(Now, "yyyyMMdd h-mm-ss tt") + _
System.Configuration.ConfigurationSettings.AppSettings("DefaultFileExportExtension")

Response.AppendHeader("content-disposition", "attachment; filename=" & FileAndPathName)
Response.ContentType = "text/plain"
Response.WriteFile(Server.MapPath(New Uri(DirectoryPath).LocalPath))
Response.Flush()
Response.End()


I'm using my laptop as a server (which works in all other respects) so do I need to distinguish between 'localhost' for development and the proper server name for deployment?

This is driving me nuts!
 
DirectoryPath isn't a file, it's a folder, so you can't WriteFile it. You can by the way use a relative file path and MapPath will translate it to absolute local path.
 
Not quite what I'm asking ...

First, thanks to everyone for posting replies promptly however they aren't answering my question which I therefore haven't asked correctly.

1. This is a production application and I don't have any issues distinguishing between localhost and the production server name. These are all correctly resolved from values in my web.config file.

2. I can write to the web server without any difficulty. Again the directory path is retrieved from my web.config file and I've given write access permission to the aspnet account for that directory.

I'm writing a simple csv file as a way of exporting data from the application that can be quickly and easily opened using Excel. Again this works in my local environment because I can access the local hard drive after the file has been written.

Where I'm having difficulty is in achieving either of the following results:

1. Write the file directly to a user's hard disk, not the web server

OR

2. Read the file back from the web server using the standard HTML FileInput control

I already use the HTML FileInput control to load files from a local hard drive and store them in my SQL Server database and I can get these back out again without any trouble. One option is to generate the csv file directly into the database but I haven't been able to find anything that lets me do this either. I was hoping that if I could open the file after writing it to the web server I could then use existing code to put it in the database like all other files.

I've tried using other code that writes to temporary files but this doesn't work, possibly because the aspnet account doesn't have the appropriate permissions.

I apologise if I appear to be a bit naive but none of the responses provided so far appear to address these questions.
 
To force a "Save As" dialog in order to let the user save a file in their local harddisk you have to use the code Paszt provided in post 3. The problem in your post 5 as I said, is that you call Response.WriteFile with a path to a folder when you have to supply a path to a file. WriteFile must write a file. The 'filename' directive in content-disposition header must be a filename without folder path, because only the user is allowed to specify where to save that file locally, it's the users machine and you don't have access to that from your web application.
 
I'm getting closer but ...

Thanks for that John.

I've changed my code as follows but now get an error about an invalid URI.

Here's the code:

Response.Clear()
Dim Pagename As String = "FileCCN"
Dim FileName As String = System.Configuration.ConfigurationSettings.AppSettings(Pagename) + _
Format(Now, "yyyyMMdd h-mm-ss tt") + _
System.Configuration.ConfigurationSettings.AppSettings("DefaultFileExportExtension")
Response.AppendHeader("content-disposition", "attachment; filename=" & FileName)
Response.ContentType = "text/plain"
Response.WriteFile(Server.MapPath(New Uri(FileName).LocalPath))
Response.Flush()
Response.End()


And here's the error:

Invalid URI: The format of the URI could not be determined.

I've debugged and checked that I only have the filename with no path or directory information so what do you think is causing this error?

Thanks again!
 
Try to do something simple before getting tangled up in functions and classes you don't understand what is, for example place a file "test.jpg" in c:\ root folder (given the web app has permission to read this folder) and try these in place:
VB.NET:
Response.AppendHeader("content-disposition", "attachment; filename=returned.jpg")
Response.WriteFile("c:\test.jpg")
Try also to put a path here "attachment; filename=c:\bogus\returned.jpg" and see what the user will get, ok reveal: the user will get a suggested filename of "c__bogus_House2.gif", ie the path is discarded.

Now put the file "test.jpg" in root folder of the web application and try substitute to this line
VB.NET:
Response.WriteFile(Server.MapPath("test.jpg"))
Read the documentation about the MapPath function to see what it is meant to do, also try it out get some simple debug info, place a label control in the page and run this code, see what it translates to:
VB.NET:
Label1.Text = Server.MapPath("anything.jpg")
After that if you have a need for it, read up on the System.Uri class to see what it does and if it would benefit your usage.
 
Back
Top