实体框架4和sql文件流从数据库读取文件

发布于 2024-09-24 02:17:53 字数 781 浏览 1 评论 0原文

我在 SQL 2008 中使用 ASP.NET 4、EF 4 和 FILESTREAM 向数据库添加/读取文件。我可以很好地上传文件,但无法按照我想要的方式检索文件。这就是我正在做的 -

  1. 我有一个显示文件列表的网格。每个行项目都是一个带有 CommandName 和 CommandArgument 集的文件。
  2. 用户单击这些文件中的任一文件,我会在 RowCommand 事件中捕获该事件。此时,我获取了文件的 ID 并从数据库中检索了 byte[]。如何显示标准下载框供用户保存或取消下载?

我可以将流写入临时文件(使用 System.IO.File.WriteAllBytes),然后对临时文件执行 Server.Transfer,但我认为这是不必要的步骤。有没有办法,我可以直接将字节读取到内存,然后设置 ContentType/MimeType 并允许用户保存文件?

我知道使用 T-SQL 访问 FILESTREAM 文件比使用 WIN32 API(使用新的 SystemFile.PathName() 和模拟的组合)访问文件流文件要慢,但 EF4 使使用 SQL 更快,所以我要走这条路。

这是代码 -

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.

感谢您的帮助!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凡尘雨 2024-10-01 02:17:53

您可能想要创建一个 .ashx 处理程序(假设您使用的是 asp)并创建一个指向该 URL 的 Server.Transfer() 或 Server.Redirect() 。

或者,您也可以更改 GridView 以显示指向处理程序 URL 的超链接。

右键单击“解决方案资源管理器”>新商品> ASP.Net 处理程序。

处理程序代码:

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);
  }
}

您可能还想添加一些错误检查。

您的 URL 将类似于:/DownloadFile.ashx?fileID=somefileid

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文