在运行 ASP.NET 的网站中,如何显示存储在 MS Access 2007 附件类型中的图像
Posted
技术标签:
【中文标题】在运行 ASP.NET 的网站中,如何显示存储在 MS Access 2007 附件类型中的图像【英文标题】:In a website running ASP.NET, how can I display an image stored in an MS Access 2007 Attachment Type 【发布时间】:2010-06-18 12:48:27 【问题描述】:背景: MS Access 2007 添加了附件字段类型,可以在其中存储图像。 我正在使用 ASP.Net 和 .NET 框架 4 构建网站
那么,在不使用 Silverlight 的情况下,从服务器上的 Access 数据库中检索图像并用作 Image 控件的源的最简单方法是什么?
举个简单的例子: 在面向儿童的 ESL 网站中,单击“A”会显示一个苹果; “B”熊等
注意:这是一个 A2007/A2010 附件字段,而不是二进制对象
【问题讨论】:
您是否暗示要从中检索图像的访问数据库是在客户端计算机上 ...? @Silky;我已经更新了问题以澄清数据库在服务器上 我建议不要使用附件字段,因为 ACE 中的目的是为了与 Sharepoint 兼容。真的,只有 Sharepoint 和 A2007/A2010 知道如何处理附件字段,所以坚持使用它们只是在给自己买麻烦。 @David,这可以解释为什么关于如何使用该字段的文档如此之少。但由于它没有标记为内部使用、限制或可能更改,我想使用它。 我会说你在浪费时间尝试使用它。一般来说,无论如何,我认为将二进制文件存储在数据库字段中是一个坏主意。获取数据存在太多问题,在大多数情况下,这样做几乎没有任何好处(与将二进制文件存储在文件系统中并将路径/文件名存储在数据库字段中相反)。 【参考方案1】:您可以将图像作为二进制 blob 从数据库中读取。这将作为 byte[] 数组读出。然后可以使用 Response.BinaryWrite 和 image/(type) - jpg/png/gif 的内容类型将该字节 [] 发送到浏览器。
调用看起来像:
<img src="showmyimages.aspx?image=id" />
代码看起来有点像:
结果 = myWebService.GetImage(id);
if (result != null) && result.Length > 0
Context.Response.ClearContent();
Context.Response.ClearHeaders();
Context.Response.ContentType = "image/gif";
Context.Response.AddHeader("Content-Length", result.Length.ToString(System.Globalization.CultureInfo.CurrentCulture));
Context.Response.AddHeader("content-disposition", String.Format("inline; filename=0.gif", filename));
Context.Response.BinaryWrite(result);
Context.Response.End();
这会稍微掩饰图像的文件名,但它允许直接从数据库中读取二进制文件,而无需在磁盘上保存永久图像。
编辑:
我所读到的关于附件字段的所有内容都是它作为直接二进制存储在数据库中,就像它直接保存到文件一样。我没有尝试为此编写任何代码,但可以想象,如果可以将二进制数据输入 StreamReader,则无需转换,甚至可能使用WebResponse.GetResponseStream()
编辑:
我能够使用以下代码实现一个处理程序,该代码实际上从附件字段中提取二进制数据(可以在调试器中验证),但是似乎涉及未内置的编码。关键似乎是检索fldImage.FileData
的select 语句。
public void ProcessRequest(HttpContext context)
string qry = "SELECT [Image], ID, [Images.Image.FileData] AS FileData, ";
qry += "[Images.Image.FileName] AS FileName, [Images.Image.FileType] AS FileType";
qry += " FROM Images WHERE (ID = 1)";
string connect = @"Provider=Microsoft.ACE.OLEDB.12.0;Persist Security Info=False;Data Source=##PathToDB##\Database1.accdb";
using (OleDbConnection conn = new OleDbConnection(connect))
if (context.Request.QueryString["id"] != null)
OleDbCommand cmd = new OleDbCommand(qry, conn);
cmd.Parameters.AddWithValue("ID", context.Request.QueryString["id"]);
conn.Open();
using (OleDbDataReader rdr = cmd.ExecuteReader())
if (rdr.HasRows)
rdr.Read();
context.Response.ClearContent();
context.Response.ClearHeaders();
context.Response.ContentType = "image/" + rdr["FileType"];
byte[] result = Encoding.UTF8.GetBytes(rdr["FileData"].ToString());
context.Response.AddHeader("Content-Length",
result.Length.ToString(System.Globalization.CultureInfo.CurrentCulture));
context.Response.AddHeader("content-disposition",
String.Format("attachment; filename=0", rdr["FileName"]));
context.Response.BinaryWrite(result);
context.Response.End();
在MSDN Access Blog 中描述的 Microsoft Office 互操作库中还有一些可能有用的方法。他们描述了加载和保存文件,但看起来他们也可以直接执行相同的操作来流式传输对象。参考是Microsoft.Office.Interop.Access.Dao
。添加时,转到 COM 选项卡并查找Microsoft Office 12.0 Access Database Engine Objects Library
。我还没有测试过这种“直接流式传输”理论。
【讨论】:
+1 我只建议删除 Content-Length 并让过滤器修复它,因为如果您尝试压缩 aspx 页面会出现一些问题。 有道理,但附件是从数据库返回的字符串类型,而不是实际的图像字节 [] 本身 @Noah - 对于 blob 数据,您可能必须执行一些转换措施才能将其转换为正确的二进制编码。我不记得转换是什么(我已经很久没有尝试过了)。 @Joel,看起来附件类型将其存储为对象,而不是 blob。我得看看能不能直接施放。 此建议是否考虑了 A2007/A2010 附件字段与旧 OLE 字段之间的差异?以上是关于在运行 ASP.NET 的网站中,如何显示存储在 MS Access 2007 附件类型中的图像的主要内容,如果未能解决你的问题,请参考以下文章
如何在 http 和 https 之间共享 asp.net 会话