Fog Creek Software
Discussion Board




Welcome! and rules

Joel on Software

Autodownload a file in ASP.NET

The title sounds a little misleading, so let me explain what I am trying to do.  First off, what I need to do is to take a file from a user, and do some magical manipulation on it, and then give a file back to the user.

I started off by making a file input box on the page, and then a button that starts the process. The function then gets the file, throws it on the server, I then use the normal file functions, open, read, and parse, and write the new parsed file to the server.

Since this information is semi-confidential, I didn't really want those files sitting around on the server. So after they hit the button, I wanted the file I created to pop up one of those download dialogs for the user, and then when he/she downloads it, to delete the file.

Sounds kind of complicated, and maybe .NET doesn't have a solution to this, and if so, is there a better way? How do I give users temporary binary information and get rid of it as soon as they received it?

Thanks.

Victor Vuong
Sunday, December 01, 2002

One way to solve this is to create an empty .aspx page that contains nothing but the <%@ Page language="...":.. > tag. Then use something like the following code snippet in the form's Load-event:

-----
Response.BufferOutput = false;
Response.Buffer = false;
            Response.AppendHeader("Content-Disposition", String.Format("attachment; filename={0}", fileName);
----

Then use Response.BinaryWrite() to write the file to the client. That way, you won't have to muck around with temporary files at att. You simply do your processing in the Load-event after the code above, and write it to the client directly.

There are probably more ways to do this (for example, there is probably a way to get rid of the .aspx-file entirely), but this should work at least.

E-mail me if you want a more verbose example.

Good luck!

Karl
Sunday, December 01, 2002

"...with temporary files at att" should, of course, be "...with temporary files at _all_". Sometimes I write too fast. =)

Karl
Sunday, December 01, 2002

Hey Karl, I wrote you an e-mail, but you haven't responsed. I was thinking maybe an anti-spam filter ate it up?

I had some troubles with it... right now it's saying:

Response.BufferOutput = false;
            Response.Buffer = false;
            Response.AppendHeader("Content-Disposition", String.Format("attachment; filename=\"{0}\"", Page.Request["file"] ) );

            FileStream fs;
            long fileSize;

            fs = new FileStream( Page.Request["file"], FileMode.Open );
            fileSize = fs.Length;

            byte[] buffer = new Byte[ (int)fileSize ];
            fs.Read( buffer, 0, (int)fileSize );
            fs.Close();
            File.Delete( Page.Request["file"] );
            
            Response.BinaryWrite(buffer);
            Response.Flush();
            Response.Close();

So I got lazy and I decided to just write the file out, and then open & write to buffer, then delete. I can modify it later, but nonetheless, with this code, the autodownload works, but the fields in the autodownload information are incorrect:

filename: it says "download" which I think might be because my page name is download.aspx.
filetype: blank
location: correct

Any idea? Thanks.

Victor Vuong
Tuesday, December 03, 2002

Aah.. I figured it out. On the file name area, I was writing a full path to it, which I shouldn't have. I changed it to just a simple file name and it worked.

Sorry!

Victor Vuong
Tuesday, December 03, 2002

Victor,

Your code is a little over-complicated for my liking :-) BinaryWrite is a hangover from the old ASP days - it forces you to read everything into a humungous byte array. So, as the file is on the server use Response.WriteFile() like so:

  string filename = Request["file"];
  //TODO: Some check on the file path here!!!
  Response.AppendHeader("Content-Disposition", String.Format("attachment; filename=\"{0}\"", filename ) );
  Response.WriteFile( filename );
  Response.Flush();
  File.Delete( filename );
  Response.End(); // don't send any more content

Also you may want to consider that the file needn't actually hit the filesystem ("I didn't really want those files sitting around on the server") if you familiarise yourself with Streams, StreamReader/Writer (if it's textual) etc. you can manipulate it without writing and reading to a physical file.

Duncan Smart
Tuesday, December 03, 2002

Thanks Duncan. Yes I was going to change the way I processed things and left it in streams instead of writing the actual file. But then I just wanted to get the autodownload thing working first, and work on that later.  My original class that I used, just had a function that took 2 files and wrote out another one, so I would have to change around when those things would be called, etc.

Thanks a lot again.

Victor Vuong
Tuesday, December 03, 2002

*  Recent Topics

*  Fog Creek Home