简体   繁体   中英

Entity framework 4 and sql filestream to read a file from db

I'm using ASP.NET 4, EF 4 and FILESTREAM in SQL 2008 to add/read files to the DB. I'm able to upload files just fine, but I'm not able to retrieve the files the way I want to. Here's what I'm doing -

  1. I have a grid which displays a list of files. Each line item is a file with a CommandName and CommandArgument set.
  2. The user clicks on any one of these files and I capture the event in the RowCommand event. At this point, I get the ID of the file and retrieve the byte[] from the DB. How do I display a standard download box for the user to Save or Cancel the download?

I can write the stream to a temp file (using System.IO.File.WriteAllBytes) and then do a Server.Transfer to the temp file but I think it's an unnecessary step. Is there a way, I can read the bytes directly to memory, then set the ContentType/MimeType and allow the user to save the file?

I understand that accessing the FILESTREAM file using T-SQL is slower than accessing the same using WIN32 API's (using a combination of the new SystemFile.PathName() & Impersonation) but EF4 makes working with SQL faster so I'm going that route.

Here's the code -

var file = db.Storage.Single(f => f.ID.Equals(fileID)); // fileID is set in CommandArgument
// file.Contents has the byte [].
// display a  standard file download box.

Thanks for any help!

You probably want to create an .ashx hanlder (assuming you are using asp) and to a Server.Transfer() or Server.Redirect() to that URL.

Alternatively, you could change the GridView to display a hyperlink to the handler URL as well.

Right click in Solution Explorer > New Item > ASP.Net Hanlder.

Code for handler:

public class DownloadFile : IHttpHandler { // add IRequiresSessionState if needed 
  public bool IsReusable { get { return true; } }

  public void ProcessRequest(HttpContext context) {
    var fileID = context.Request.QueryString["fileID"]; // assuming fileID is a string
    var file = db.Storage.Single(f => f.ID.Equals(fileID)); 
    // set the content type
    context.Response.OutputStream.Write(file.Contents, 0, file.Contents.Length);
  }
}

You probably want to add some error checking as well.

Your URL would be something like this: /DownloadFile.ashx?fileID=somefileid

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM