Mattaniel
Mattaniel

Reputation: 103

How to show download dialog before file is ready to download?

I'm getting a file from a database in byte [] format and want user to see download dialog before Linq will take it from the database. It's in C# and ASP.NET.

Now, it's like this:

  1. User choose a file, click on it.
  2. In code I get id of file clicked and using Linq I'm downloading.
  3. Then I send the file by Response.OutputStream.Write(content, 0, content.Length);
  4. Before a file is downloaded from the database user won't see any download dialog.

What can I do if I want users to see the download dialog before file is downloaded?

Code:
Getting file by id:

public static byte[] getFile(Guid id)
{
    var linqFile =  from file in MyDB.Files
                    where file.IdPliku.Equals(id)
                    select new
                    {
                        Content = file.Content
                    };

     return linqFile.ToList().FirstOrDefault().Content.ToArray();
}

Saving file:

public void SaveFile(Guid fileID, string filename, string mimeTypes)
{
    try
    {
        byte[] content = FileService.getFile(fileID);
        Response.ClearContent();
        Response.ClearHeaders();
        Response.ContentType = mimeTypes;
        Response.AppendHeader("Accept-Ranges", "bytes");
        Response.AppendHeader("Content-Range", string.Format("0-{0}/{1}", content.Length, content.Length));
        Response.AppendHeader("Content-Length", content.Length.ToString());
        Response.AppendHeader("Content-Encoding", "utf-8");
        Response.AppendHeader("Content-Type", Response.ContentType);
        Response.AppendHeader("Content-Disposition", "attachment; filename= " + HttpUtility.UrlEncode(filename));
        Response.OutputStream.Write(content, 0, content.Length);
        //Response.BinaryWrite(content);
        Response.Flush();
    }
    finally
    {
        Response.Close();
    }
}

You are my hope.

Upvotes: 2

Views: 1607

Answers (1)

Davide Piras
Davide Piras

Reputation: 44605

your issue is here:

byte[] content = FileService.getFile(fileID);

because in this line you allocate the whole file in the web server's RAM and put everything in there, all content of the file from the database; what happens later does not matter anymore because you have already downloaded from db to web server in this line!!!

I am having such Deja-vu because I am sure I have given exactly the same comment on a very same question few weeks ago. Can't find it now, search for something like this here in SO.

In fact the solution is to stream directly to the output stream of the Response avoiding your byte[] array allocation above, to get this your data layer should of course support it and if it does not you could add a method for this. You want to use SQL Server filestream or something similar.

Upvotes: 1

Related Questions