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 -
- I have a grid which displays a list of files. Each line item is a file with a CommandName and CommandArgument set.
- 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 retrie开发者_运维百科ve 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
精彩评论