views:

155

answers:

3

Hi,

I am simply storing uploaded file into a binary field in SQL Server but I also need to allow users to download it with Asp.NET. How can I do that ?

Thanks in advance.

+2  A: 

Read the data into a filestream object with the appropriate extension tacked on to it, and have the user download the resulting file.

You'll want to use the System.IO BinaryWriter object on the filestream to create the file...something like this:

FileStream fs = new FileStream("thisfile.bin", FileMode.Create);
binWriter= new BinaryWriter(fs);    

binWriter.Write(varHoldingSqlRetrievedBinaryData);
Gus
Then how can I get the extension from binary data ?
Braveyard
And could you provide a sample code, because I kinda knew what you said but in code side I may need an example :(
Braveyard
there are no way to do so. The best way would be to store the extension in the database.
David Brunelle
Instead of the extension I'd recommend storing the actual MIME type string in a separate column (taken from the request when the file is uploaded to the database), so `.png` images come down as `image/png`, text files as `text/plain`, etc. Some well known CMS and forum applications don't do this properly, causing the File Save dialog to show an incorrect default extension.
devstuff
@devstuff : Thanks for the recommendation, I think I am going to do in your way.
Braveyard
+3  A: 

Here's a Microsoft Knowledge Base article on this.

How to retrieve the file from your database depends on the data access technology you use; I will just assume that you have some Byte array data containing the file (e.g. by filling a DataSet and accessing the field) and some string filename.

Response.Clear()
Response.ContentType = "application/octet-stream"
Response.AddHeader("Content-Disposition", "attachment;filename=""" & filename & """")
Response.BinaryWrite(data)
Response.End()

Put the above code in some download.aspx and link to this file. You probably want to pass some query string information to your download.aspx, so that your code knows which file to get from the database.

Heinzi
+2  A: 

Add a Generic Handler (.ashx) page to your web site. The ashx code body below demonstrates how to read an arbitrary stream (in this case a PNG file from disk) and write it out in the response:

using System;
using System.Web;
using System.IO;

namespace ASHXTest
{
    public class GetLetter : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            // Get letter parameter from query string.
            string fileName = context.Request.MapPath(string.Format("{0}.png",
                context.Request.QueryString["letter"]));

            // Load file from disk/database/ether.
            FileStream stream = new FileStream(fileName, FileMode.Open,
                FileAccess.Read);
            byte[] buffer = new byte[stream.Length];
            stream.Read(buffer, 0, buffer.Length);
            stream.Close();

            // Write response headers and content.
            context.Response.ContentType = "image/png";
            context.Response.OutputStream.Write(buffer, 0, buffer.Length);
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

If desired, you can also set the Content-Disposition header as demonstrated in Heinzi's answer:

context.Response.AddHeader("Content-Disposition",
    "attachment;filename=\"letter.png\"");
Annabelle