C# 在ASP.NET C中将字节[]流式传输到图像#

C# 在ASP.NET C中将字节[]流式传输到图像#,c#,asp.net,sql-server,image,C#,Asp.net,Sql Server,Image,我有一个存储在SQL Server数据库中的图像,它与我的用户数据一起存储,我可以一次检索所有这些数据 现在,我将字节[]直接显示在要显示它的页面上。如何将其放入我的网络控件。图像?我不想再调用HttpHandler和数据库 这显然只是将其输出到整个页面 Context.Response.BinaryWrite(user.Picture.ToArray()); 创建单独的页面,在其中创建图像,例如:image.aspx 并在其他页面上使用它 <img src="i

我有一个存储在SQL Server数据库中的图像,它与我的用户数据一起存储,我可以一次检索所有这些数据

现在,我将字节[]直接显示在要显示它的页面上。如何将其放入我的网络控件。图像?我不想再调用HttpHandler和数据库

这显然只是将其输出到整个页面

            Context.Response.BinaryWrite(user.Picture.ToArray());

创建单独的页面,在其中创建图像,例如:image.aspx 并在其他页面上使用它

<img src="image.aspx?id=number" >


number是数据库中图像的id

将字节数组包装在MemoryStream对象中,并将其放置在ASP.NET缓存中

MemoryStream ms = new MemoryStream(user.Picture.ToArray());
Guid imageGuid = new Guid();
HttpRuntime.Cache.Add(imageGuid.ToString(), ms, null,
    DateTime.Now.AddMinutes(5), Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
然后使用处理程序(.ashx)将其从缓存中取出并发送到客户端

string imageGuid = context.Request.QueryString[image];
MemoryStream ms = (MemoryStream)HttpRuntime.Cache[imageGuid];
// configure context.Response with appropriate content type and cache settings

// ** Edit **
// It seems I need to be more explicit with regard to the above comment:-
context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.Cache.SetLastModified(DateTime.UtcNow);
context.Response.Cache.SetExpires(DateTime.UtcNow.AddHours(2);
context.Response.Cache.SetMaxAge(TimeSpan.FromHours(2));
context.Response.Cache.SetValidUntilExpires(true);

ms.WriteTo(context.Response.OutputStream);
现在可以从缓存中删除MemoryStream

HttpRuntime.Cache.Remove(imageGuid);

您需要一个
IHttpHander
,它将图像字节和适当的
内容类型写入响应流。请参阅,和。

我非常确定,您不能在页面本身中执行此操作

如果您不想创建一个HTTP处理程序来输出图像,那么您可以选择创建一个单独的
aspx
页面。将
img
标记的
src
设置为指向该页面,在查询字符串中传递某种ID,以便可以从数据库中提取图像数据


话虽如此,设置
aspx
页面来实现这一点并不比设置
ashx
更快或更容易。我建议您以正确的方式执行此操作,并创建一个HTTP处理程序。

如果它是一个小图像,您可以将其作为base64编码的数据输出到图像标记中。 .



但在99.9%的情况下,您会创建一个返回图像的HttpHandler。我认为这是最简单、最快的方法。

不要使用ASPX输出图像,使用ashx。@Anthony:OP说他们不想使用
ashx
,尽管我同意这是正确的方法。(而且创建一个
aspx
并不比创建一个
ashx
简单!)安东尼:我不知道有什么不同。这是唯一的分机,不是吗?它可以是偶数.jpg,带有路由。@x2:MS将ASPX文件描述为ASP.NET表单是有原因的。它带来了与完整表单生命周期相关的相当大的开销(初始化控件、加载控件、处理回发、预渲染、渲染、卸载、处理等等)。如果您所要做的只是调整响应对象的属性并在输出中转储一块数据,那么这些都不需要。在这种情况下,ashx是一种更简单、更干净的解决方案。@Luke:OP想要避免处理程序的原因是为了避免不得不再次从DB中读取图片,我认为这并不是对处理程序本身的厌恶,只是为了避免不必要地重复一个重要的操作。这不会在网络农场中扩展(除非您有某种分布式缓存)。永远不要这样做。您正在牺牲HTTP的所有优点(
,如果自
以来进行了修改,缓存等)可扩展性绝对没有任何好处。@anton:你看到我代码中的注释行了吗?你认为我的意思是什么?@Luke:恰恰相反,充分利用web服务器场正是使用缓存的好处。在WLB环境中,会话可以而且通常与服务器场中的服务器关联。拥有Web服务器场将承受数据库层的压力,而缓存是该解决方案中非常重要的一部分。@Anthony:示例代码中使用的内置ASP.NET缓存不是分布式的:每个Web服务器都有自己的缓存。如果您的映像请求命中不同的服务器,则在其缓存中找不到映像数据。(如果您的webfarm使用粘性会话,这显然不适用,但这有其自身的可伸缩性问题。)你错过了问题的重点。假设你在一个正在执行的ASPX页面中有一个从数据库中获取的图像数据字节数组,你如何获得
@Anthony:关键是他不需要从页面本身的数据库中提取图像数据。他不需要重新查询数据库-他需要查询一次在适当的地点/时间(即,在单独的
ashx
处理程序中。)@卢克:可能是这样,但我们不知道,是吗?我们从这个问题得到的只是,出于某种原因,他有一个已经加载了图片对象的对象。也许这可以更好地避免,但可以将图片放在文件系统中。我更愿意回答手头的问题,特别是因为其他SO用户可能会在某个时候发现他们这也是我在谷歌上找到的唯一解决方案,但对我来说毫无用处,因为我已经有过一次数据库中的数据,不想浪费另一次通话。你不能将图像数据存储为文件吗?这是第一条路线,但将图像存储在数据库中是首选解决方案。(在我头上)因此,我必须充分利用这种情况。感谢所有人的帮助。快速而深刻的回答。嵌入base64映像是最后的选择。即使有额外的DB流量,您最好使用单独的请求,以便页面响应更迅速。还有。SqlReader类作为VirtualPathProvider发挥作用,这给了您更好的性能比HttpHandler更高的性能。您可以将其与DiskCache插件结合使用以获得非常好的性能。我已经从数据库中获得了数据。我想保存另一个调用。这正是我要查找的。图像是一个180 x 160 px的小gif/jpeg。结果如下:byte[]picByteArray=user.Picture.ToArray();string myPicString=Convert.ToBase64String(picByteArray);myPicture.Attributes[“src”]=“data:image/gif;base64,”+myPicString;@Markoo:base64编码时会有多少字节?通过将图像数据直接放在动态生成的HTML中,您每次都需要客户端获取它,除非您将整个HTML响应缓存起来,否则它是不可缓存的